Jump to content
Site Stability Read more... ×
  • Advertisement
  • entries
    109
  • comments
    175
  • views
    118357

About this blog

This journal is approved by the Get A Life Commitee. I swear.

Entries in this blog

 

Yeah! The sun is shining

Good to see that the sun is shinning (not now, during the day, you know). And the real good news of the day: I received my copy of A Theory of Fun for Game Design. A quote, p189: 2B||!(2B). This is not a valid C expression. This guy doesn't know how to program. I want my money back (kidding. It seems to be an exceptionnal book so far).

No, I go to bed again - no MMOMSF1 tonight.


1: massively multiplayer online "mine sweeper flag".

Emmanuel Deloget

Emmanuel Deloget

 

Yeah !

I'm happy.

My gdnet+ membership had been renewed for another year. I'll still be there and there until (at least) dec 2006. Prepare for another year of

(not funny) humor
(not very accurate) technical rambling
(not very accurate) C++
newbies bashers bashing
falling in love with caitlin each time she posts a new photo
(dull) posts
(irrelevant) PMs
bad English and French words


Maybe I'll have time to

learn C#
learn how to program
learn why I want to program
learn C++ (would help)
learn more English and French words
get rich
rul3 teh wArld!!!111


I also have tons of projets, maybe I'll try to get some help from you in a near futur [smile]

Emmanuel Deloget

Emmanuel Deloget

 

Wow. An alien.

News 'n stuff
Customizing this journal is not so complex after all. It may be dangerous but not complex (I hope noone will try to misuse this great opportunity).

I added some links in a column on the right. I'm happy.


O_o
._.
;_;


My html skills are teh sux0rz. Like my notebook kebord.

Anyway, let's continue my "design course" (can I call this a course? I think it is obvious that my goal is not to design my 2D engine but to show how I design it, and why I design it this way).

Three components and one "little" deflection
I'm not sure deflection is the right word to use. Damn, I'm still unable to write correct english sentences (yeah, I know, I'm teh sux0rz too).

Last night I started to speak about design patterns. I made it clear that a game is made with data, algorithm, and a representation of these. Datas and algorithms can be abstracted as the model, and their representation is of course the view. We need the last one to complete the holy trinity: the controler. This is not difficult to locate it: the game input system is a very good candidate - and for now we'll stick with that.

You got it: this is one of the most famous mecanism: the model-view-controler, or MVC for those who are intimate with him. The MVC is well-known for its ability to be mapped to useful design patterns. Maybe we'll be able to study this in details in a subsequent journal entry (read: certainly not today, and maybe never. I'm dumbass ;)).

For those who don't know how the MVC works, let's define it using simple words. To a view is attached a controler. The controler is responsible for handling (for example) user input. In response to these inputs it modifies the model. In response to this modification, the model updates the attached views. You can learn more about MVC in [1].

MVC implies that the view knows how to represent the data. Since we are developping our graphic engine as a "component-on-the-shelf" (COTS, see [2]) we don't want the engine to know the model. Remember, We have discussed this issue in a previous journal entry. When we consider both predicates (the view knows the model and the graphic engine does not knows the model) we clearly see that the view component of the MVC must be split into two different components: the first one is the graphic engine itself. The second one is some kind of glue which will be able to transform a model into its representation.

The glue object interface may use the observer design pattern. In this pattern, the subject (the model in the MVC) sends an update() message to all its observers when it is modified. Let's do this more clearly using a pseudo C++ language:


class Controler
{
World w;
modifyWorld() { w.update(); }
public:
onUserInput() { modifyWorld(); }
};

class World
{
View v;
updateView() { v.draw(this); }
public:
update() { updateView(); }
};

class View
{
set gels;
GraphicEngine ge;

drawElement(GraphicElement gel)
{
ge.draw(gel);
}

public:
draw(World w)
{
updateGraphicElements(w);
for_each_element(gels, drawElement);
}
};


This pseudo codes shows how we can create a game which is independant from the view. If we want to modify the view (maybe adding a third dimension) then we only have to modify the view. This is of course not simple - it may need a lot of work. But it is far better than modifying the whole game!

What else?
I believe I have to speak about the GraphicEngine itself again... Yeah. I may do that...

References!
[1] Glenn E. Krasner and Stephen T. Pope. A cookbook for using the model-view controller user interface paradigm in Smalltalk-80. Journal of Object-Oriented Programming, 1(3):26-49, August/September 1988.
Some info can be found on wikipedia
[2] COTS are discussed at cmu.edu - they appear to name them "commercial-on-the-shelf" because of the nature of teh components themselves. For our purpose, what we want to create is really a COTS-like, not a real commercial component, hence my initial pick: "component-on-the-shef".

PS: it seems I can't remember how to create an anchor in da html. Let's do that next time...

Emmanuel Deloget

Emmanuel Deloget

 

Wot ? I am Living ? Strange...

Apologies...
As you might have seen; I was quiet these last days. This is because I had some bad news (nothing awful... just a set of bad news). It killed my mind and I had to face a lot of migraines. This is not dangerous fro my life, so don't cry.

The problem is more that I was barely unable to think during these last days, so I didn't do my homework - to be fair, my day work also suffered from the situation.

Helas, no homework == no text RPG update. That's the sad thing. I need to hurry up.

Some work to do
Fortunately, I know where I want to go (that's something cool, since I don't have any functional specifications for the product).

There is two steps in this project: the first step is to design a correct (but not excellent) solution. As I already said in a previous post, the solution can be improved using other technologies - EDI and other already pointed scripted languages. The second step is to create an application that will use this design. In order to be a usefull tool, the application needs to be somewhat complex. Obviously, this is the case: I have to make a text based RPG, and these beasts are never simple.

I have some good news for you: the second step is nearly completed. Hopefully, I'll be able to give you a full text game in a few days.

But remember that this is not my goal. The real goal of the project is to give you some hints about how to design an application, not to deliver you a game. It means that I have something more important to deliver - and that's still a big ToDo.

Roadmap
finish the game code, with full comments: deadline on April the 16th
finish the BIIIIIIIIIIP: deadline on April the 30th
Then, you'll just have to send me some money (to my paypal account)
I may have some cool stuff for you during the few comming days.

Next project
I am already working on my next project, as some already knows. And this is super mega secret (well, not much. You might be able to find some clues about what I'm doing right now on these boards), so I won't talk about it, even if you try to torture me.

Emmanuel Deloget

Emmanuel Deloget

 

Where is my time?

Really, I don't know.

It seems that my day is split in two parts: the sleeping part, and the "running everywhere" time. And that's a bit annoying.

On the good side, I'm doing a lot of stuff. I'm still working (you remember?) at Alpine in Stuttgart, I'm searching new news for you (I believe I'm the official GameDev.Net spammer), I'm blogging (well, I try; I was supposed to update my blog every week, and I haven't found the time to update it last week), I'm preparing the coverage of the fmx/07 (people to meet1, talks to attend, questions to ask, and so on), I'm trying to answer questions in the forum, I continue to work on SOMETHING, I'm taking care of my xperteleven.com team in the GameDev.Net league (today, I won!), and I'm running after womentrying to get a correct social life (seducdiscussing all sort of stuff with very beautifinteresting gir people).

No wonder why I'm a bit tired...

Anyway, I'm pretty sure you don't care much (well, maybe the stuff about gdnet), so let's talk about something more interesting.

There are lots of news that we don't feature anymore. In fact, we don't feature alpha/beta/unfinished product anymore. The reason is that we want to focus more on real products: finished engines/middlewares, with their documentation, samples, and a full feature list.

We also don't feature jobs anymore (but then, we haven't got any job news for the past century). The gdnet Job feature is a better way to advertise jobs anyway.

We also try to avoid publishing news about new websites that doesn't have much interest. In the past, we used to advertise these websites on our frontpage, and that's not really relevant - especially if these sites are q mere collection of links. Of course, if a particular web site draws our attention, we're likely to feature it on the front page).

Last but not least: we don't feature games. We are not a gaming web site. So forget about the release of your "fantastic rpg v0.42" - it's not going to be featured here.

The good thing is that even if your news is not features, you still have the possibility to post an announcement in the dedicated forum (which is called, guess what, Your Announcement). Our standard reply is usually something along the line of "we won't feature **** because ****, but you can still post to the YA forum".

More rarely (but it happens), our answer can be "your post = spam. My action = ban. I win. Ah ah ah."

I say this because, whatever you might think about gamedev.net, we don't sell rolex replicas. We also don't support phising, so don't send us news about how cool it would be to automatically become a RuneScape mod by logging here.

Of course, all this is subject to change. We have Secret Plans for some changes, and I believe you'll be surprised by the result (or not). PM me if you want to learn more about that (don't forget that if I tell you anything, I will have to kill you. How curious are you?).

Ok pals, see you later!


1: speaking of that, I have a surprise for you (no, I won't tell it right now. you'll have to wait for another week) a question: I have the possibility to interview a major film director (hint: his name begins with "Rolan", it ends with "mmerich", somewhere in the middle you'll find a "d" and a "E", and back in time he did a small budget movie about some kind of door that would lead a bunch of military and a scientist to another planet with an egyptian-like setting). So the question is: do you have any interesting question to ask? To be honnest, I don't.

Emmanuel Deloget

Emmanuel Deloget

 

What a good idea...

I've just got an idea, something not very complex (it may need nearly one or two days of work). I noticed that there are a lot of questions on the beginner's forum where new users claim that they want to make text-based games - RGP style, full with rooms, actions, monsters and so on.

So, why not doing one ? After all, it is not very complex, and is a good design excercise (especially if you want to make it in order to teach something to C++ newcomers).

So let's see what are our needs

room display - display informations about the room; the information may change, based on past user actions (for example, a monster can be killed)
user input should be carefully handled - I don't want the user to type things that will crash the game, and I want the system to be fairly simple (the action set is fixed by room)
the game model should not be dependant on the console to work (hey, I have preached the MVC in games paradigm for at least one year, and I would make a game that ignore it?).
room description should be read from a file (the main question is: do I need one file or one file by room ?)
there is some kind of RPG combat that will need some kind of RPG rules. It is not a real problem, it is just... complex :) Anyway, I prepared a complete article about developing a RPG system (actually, it was about using design principles and design patterns, the RPG system was only to make the article game-oriented; unfortunately, I never finished it [sad]) , so I know the problem rather well.
there should be some particuler actions - jump over a pit, for example, may require a special test.
there should be monsters, treasures, hidden treasures and secret rooms. Ah ah ah ah! And maybe a beautiful princess. Unfortunately, it can't be naked - for obvious reasons.
no need for scripting - I'd want to keep everything simple; as a consequence, the game logic will be entirelly hard coded.
the user shall be able to load and save his progression.
the user may undo one operation. Ok, I understand that it is rather powerfull, but when you are killed because of a poisonous trap in the very last room, it can be... well, you know.
last but not least I should earn at least 20.000.000 bucks with this game. Or I may distribute it for free, with the source code. I don't know...


Of course, there are a lot of other needs (I guess I'd speak about them in subsequent journal entries).

Be prepared to suffer some boring entries about software design again :)

Emmanuel Deloget

Emmanuel Deloget

 

We create worlds ! Well, at least, we try...

Hey! I had some feedback about my singleton entry - not as much as I was expecting, but I still had some feedback :) Thanks a lot!

I finally decided how I'll present the results of my little "how to maek a 1337 RPG system" study. I'll write a very very long article about to explain the choices I made - how I made them and why they are good choices. After all, this is a software design course, not a programming course [smile].

Now, fight !
That's what I'm doing. I'm fighting against myself (and Ogre3D, but that's another project - let's forget this for the moment).

My main problem is about the fight manager - you remember, the FightManager class that implements a fight. It is rather tricky to implement it because I decided to implement a generic rule library that should not assume how it will be used. Of course, I must make some implementation choices that have an impact on the library interface but I can't enforce a particular game play choice. For instance, typical text games are often turn-based (at least during the fight management) while 3D games are often real-time.

This enourmous difference, of course, have a great impact on how things should be designed.

For example, in a 3D RPG, the player won't wait his turn in order to kick this horrible creature with his blade - the user will simply move the mouse and wait for the resultion of the action. It means that I have to provide a way to intriduce the user input into what's typically a loop (something like a "do { } while (somebody is still alive)").

Another example is how to deal with the output: in a text-based game, I'll write everything on the screen; in a 2D RPG, I'll se the actions of the NPCs - I'll see their weapon move and so on. As a consequence, I can't hardcode the result of an action - and, again, I have to tell the main engine what the results of the actions are.

Finally, the end condition of a specific fight may change. For example, the player's enemy might surrender, or the player may flee. I can't hardcode this too.

Design patterns to the rescue!
Again, design patters come to our rescue.

The first problem can be solved using an abstract factory. This abstract factory is influenced by the user input - for example, the factory can ask to the user what he wants to do and he will create the corresponding action.

This action is a strategy. Its role is to implement the algorithm that will impact the attacking creatature and the defending one. It will also be responsible for the UI reporting (display the action results).

The end condition problem is also correclty handled by using a strategy that will be responsible for the evaluation of the current fight state and that will tell us if we need to stop the fight.

Progress
I only added 2 classes to the project today:
Damage: this class handle the damage along with their type (fire, ice, poison, weapon, and so on).
Condition: this abstract class handles a condition - it defines a isTrue() virtual method.
It's cool, isn't it? [smile]

Update
I'm still playing with StarUML. There is two other small problems with the reverse engineering tool:
It adds the return type "void" to your model when your methods don't return anything (just because the method prototype is "void something()")
the associations are not good: they should be either compositions or aggregations, not just simple associations. Plus, the software can't handle the standard libary correctly (it should add the correct association type and change the multiplicity accordingly; instead of this, it just generates a std::vector variable in the class).
Plus, the interface to add a class then a method then some parameters is rather unproductive.

Emmanuel Deloget

Emmanuel Deloget

 

Warning: you just got a brain cancer.

About init() and uninit()
First, I feel I have to justify the name. As TANSTAAFL pointed out in a previous post, init() and uninit() are really poor names. As a programmer, I perfer create() and destroy() to them. Anyway, I'll stick with these names until we hit the implementation for two reasons:
although they are poor and not very descriptive, their meaning is clear enough to fulfill our needs for the time being.
I have to bear the burden of my previous mistakes... :)

What do these function do? The second one is easy : uninit() will do the exact contrary of init(). Now we cannot define init() as a function that does the exact contrary of uninit() anymore so we'll have to find a better answer.

What does it need to do? It has to make sure that the graphic subsystem is correctly initialized. If it is not, then it must return an error. It must also ensure that we are now able to draw what we want to draw - this phase is a special part of the setup phase: you initialize the underlying rendering state machine to satisfy the needs of the application when it is able to accept your orders.

Here comes the problem: how to initialize a graphic subsystem (probably using a known API) in the first place? I'm not speaking of DX or OpenGL init here. I speak of what they need. In extenso: who is responsble for creating the window?

Our problem is that the window may also be used by other subsystems because of its proeminence in the windowing system design. You may think that I speak about Windows here - and you are wrong. Any windowing system I used (I used quite a few, from Win32 to TVision (yeah! remember da ol'time), from GTK+ to plain XLib) are using more or less the same contests: the input is tied to a particular window. Therefore we not only need the window to deal with the rendering but we may also need it to read the user input. Because of this reason, we are not able to create the window during the graphic engine initialisation.

It means something important: we need to build our graphic engine on top of another software component: the system component, which will enable us to perform all the tasks we need to perform - ranging from reading user input to render the view on the user screen.

We are still lucky - because we don't need a full abstraction of the system application model. We only need a simple way to deal with these things - using the Win32 system, we'll only have to write a bunch of thin classes. The only thing we'll have to worry about: we need a level of abstraction which is good enough to be able to manage systems which do not have any kind of window management.

We'll speak about this is a subsequent entry.

Headache
I'm ill. Cold. See you next time? I promise I'll do my best to give you more information :)

Emmanuel Deloget

Emmanuel Deloget

 

Video game source code

This is more or less a reminder, as most of you already know this stuff. Here is a (incomplete) list of games whose source code is available, together with links (or, when not available, information on how to retrieve the source code). The origine of this entry can be found on my own personnal French blog.

Gish, Cryptic Sea.
Aquaria, Ryan Gordon (via mercurial)
Quake III, id Software (direct zip d/l)
Quake II, id Software (direct zip d/l).
Quake, id Software (direct zip d/l)
0 A.D., Wildfire Games.
Rise of the Triad, 3DRealms
Ryzom, Nevrax (stopped business a few years ago ; the game is now supported by another company)
Seven Kingdoms, Enlight.
Arx Fatalis, Arkane Studio
Return to Castle Wolfentstein single player and multiplayer, id Software (sirect zip d/l).
MechCommander 2, Microsoft
No One Lives Forever 2, Sierra : toolkit contains the source code of the game
Wolfenstein: Ennemy Territory
Duke Nukem 3D, 3DRealms
Lugaru, Wolfire Games
Penumbra - Overture, Frictional Games, via git
Alien Swarm, on steam (the source code is available in the SDK (URL = steam://install/513 ; you might need to install Steam to get it)
Allegiance, Microsoft

This is not (by far) a complete list. Some old games have been removed (mostly Doom-generation and before), some other are missing (Allegiance ; anybody have a link on this one ? It seems it disapeared from MS Reasearch downloads ; Hexen, Heven II and Heretic: cannot find a reliable download site; The Operative - NOLF : went AWOL a few years back, the Wayback machine doesn't help much ; and so on).

Do not assume that this post is not connected to my previous entries. There are evil forces in this world you can't know anything about, and I'm in a deal with some of them.

Emmanuel Deloget

Emmanuel Deloget

 

Tidbits

Nothing really fancy to say, so let's try to enhance our culture...

Christmas is comming, so I allowed me to give some presents to myself (good boy, isn't he?).

Vitalic's Ok Cowboy: this is a really good piece of techno, whith very big titles (Poney Part 1, No Fun or the slower Trahison)
I decided to give a try to Francois Ozon, a French movie maker. I went to the theater and saw Le Temps qui Reste, the story of a man who knows he's going to die from a cancer.
I bought some books by Isaac Asimov and Roger Zelazny, because I love reading them ;)
I also bought some comics and mangas: the 5 first tomes of Hisashi Sakaguchi's Ikkyu, Tessa, Agent Intergalactique [FR], t11 to 13 of Samura's Blade of the Immortal (L'Habitant de l'Infini is the French title)

I also bought some other CD (Paris Combo live, Gotan Project's Inspiracion Espiracion, and Pink Martini's Hang On Little Tomato).

Now, I really need some money.

Emmanuel Deloget

Emmanuel Deloget

 

The story of the story of the story of the story o

Day D-1
Tomorrow I'll have an English exam. Nothing very fancy. But I'll know whether I'm good enough to speak 1337 English or not. Oh, wait. I already know.

I'm teh sux0rz at English. Just forgotten that. Crap.

Graphic elements
Yesterday we decided to create an adapter to the graphic driver. Of course, since we are doing this, the first thing will have to do is to define the new interface of this graphic driver adapter (I called it GraphicDriver - the one in the system package is DisplayDriver). And to define it, we need to know what a GraphicElement is because once we are able to say what it is we are able to say how it should use the GraphicDriver.

So, what is a GraphicElement? We have at least three possible choices.

a GraphicElement is a bare resource, for example a texture. In this case the granularity of the DisplayDriver resources encapsulation is very low - and it doesn't seem to be the correct solution.
a GraphicElement is an intelligent resource - for example, a sprite or a tile. This could be a possible solution.
a GraphicElement is the representation of an in-game object - for example, the player representation or the world representation. A GraphicElement may then hold multiple intelligent resources. This solution seems to be good too.


Once we consider the last possible solutions, the first one is obviously a bad choice. The encapsulation of a system resource should be a graphic resource, and a graphic element should contain them. While being a bad choice, the solution reminds us that we will need to encapsulate the system resources in order to ease their use.

Now we have to choose among the two other solutions. If solution 2 seems to be pretty it is less high level than the other one. Moreover, to define the kind of objects which would be implemented in solution 2 we used a magic word: resource. This should give us hints that would help the design. I'll choose solution 3 because of this hint. Sprites, tiles or tile sets can be implemented as high level resources - which in turn can be implemented by using low level (read system level) resources.

Although the object names would probably need a rework, we now have something like this:


class LowLevelResource
{
system::DisplayResource rsc;
};

class HighLevelResource
{
set llrsc;
};

class ConcreteGraphicElement : public AbstractGraphicElement
{
set hlrsc;
public:
create()
{
create some HighLevelResource items
populates hlrsc
}
destroy()
{
destroy the items in hlrsc
}
virtual draw(GraphicDriver gdrv)
{
setup gdrv
draw the different hlrsc items
}
};


The main point now is that the graphic engine user is now responsible for creating the ConcreteGraphicElement objects.

Teh Xtrab0lz!
I manage to not write "Teh xtr3b0lz0rz", which may have been too much 1337 for you, young padawan.

The next time we'll speak about the low level and high level resources. And we'll explain things about these two entries. Yeah. Any comments?

Really?
Oh, come on! Stop h2'ing your questions. You look like a 10 y.o.

Emmanuel Deloget

Emmanuel Deloget

 

The Return of the Giant Mummy: Revenge of the Unde

I write this while my gf is sleeping. There is something I still don't understand concerning my relation with computers. I mean, she's a girl, so she is probably more interesting than my notebook. But I continue to speak to my notebook (you know, the one with a sux0rz kebord).

Lack of updates
I told you, I was ill. I can't sort ideas when I'm ill. So I didn't write anything here during that time. But now, I'm fine.

I just remember that you don't bother with this kind of information.

A poor graphic driver in a poor graphic engine
This is probably the central part of the graphic engine. On Jan-26 we saw that our graphic engine tells the graphic elements to draw themselves. To be able to do this, they need to use a graphic device driver (let's call him the graphic driver) which is able to handle low level resources.

Now, who does instanciate the graphic driver? As I see it there is two possibilities.

First, as it name implies, the driver can be viewed as a system resource. Therefore, it should be created by the system framework (just as the display and the input objects). This sound rather logical but if we dig further then the problems are coming. For example, the driver will probably need to expose some resource creation methods - and these resources looks like graphic objects. Therefore the graphic driver should know what is a graphic object - and therefore it should know some part of the graphic engine. Which is plain stupid since it adds a circular reference in our design.

The second solution avoid this problem: the graphic driver, although it seems to be a system object, is considered as a graphic engine entity. The graphic engine is responsible for its creation. The problem we now have is that the graphic engine now relies on a system object. But is this really a problem? Let's see the biggest impact of this solution: it makes the graphic engine dependant on the platform, which is not what we want. We are lukcy, because this dependance can be avoided using a clever directory structure (a la Loki). But this is an implementation trick and we should not speak about these now.

Inside or outside?
Each possible design seems to be the complete contrary of the other. Actually they are, because they are using a diferent paradigm. One tells the graphic engine: "hey, you should use this driver", while the other tells "the graphic engine is using this driver".

Our main issue is that it seems that none of the proposed solution is acceptable.

Well, this is not really true.

Let's consider our first solution. I told you that the graphic driver resources are graphic objects. Indeed they are: it sound weird to not consider a texture (for example) as a graphic object. But we can view the problem using another point of view: "I am the graphic driver, I'm a system object, so why don't you consider the resource I create as system objects?". After all, this is equally true. For example, a DX texture holds a reference to the underlying IDirect3DTexture9 object, which may be considered as a system object if we consider IDirect3DDevice9 as a system object too. Using this point of view we don't need the dependencie over the graphic engine anymore - basically: we solve our problem.

Now, let's have a look to the second solution. The engine creates the driver - and therefore the code of the driver is inside the engine itself. This does not allow us to transparently plug another driver - because only one driver is known. Is i a problem? To answer the question, let's ask another one: why do we want to plug another driver into the system?

I am hearing your answers: "because maybe there is a more efficient driver". Then we should use it and discard the first one. "But maybe it would be good to support multiple platform". You mean: at the same time? No matter what your answer is, you'll be able to find arguments who defeat the purpose of supporting multiple drivers at a design level. Of course, when it comes to implementation, maybe we'll create more than one driver. But the key word in the later sentence is implementation. And the answer to this problem had been written some paragraphs ago: Loki does it, so why don't we use a clever directory structure? A single compilation flag will enable us to produce a program which will use one of the 88 driver we wrote. We can even create a driver which is in fact a driver loader - which will load a particular driver at run time.

So both are good
Yes (well, as of today, it seems that both solutions are acceptable. Remember a design is an itrative process. Maybe we'll ffind another problem concerning one of these solutions).

You may ask: "why do you say that? Now we don't know which model to choose!".

There is one important thing about design that I didn't said already. There is more than one correct design. This sound obvious but is often forgotten. When we design, we often try to do our best. Sometimes, we have to choose between two or more solutions. When one is obviously better, hen we have to choose it. But when they are equally good (or, since it may happen sometimes) equally bad, where is the problem then?

Rule of thumb: don't create problem where there is no problem :)

And the winner is...
I won't tell you who wins :) Since you already knows that the two solution are correct, the one I pick is only a matter of taste - and I must encourage you to develop your own taste ;)

Anyway the result is there: now, we have a graphic object to manage. Wether it has been created by the engine or given by the system is not really our problem, since it does not change the representation.


class AbstractGraphicElement
{
public:
virtual draw(GraphicDriver gdrv);
};

class GraphicEngine
{
GraphicDriver gdrv;
public:
init();
uninit();
draw(AbstractGraphicElement gel) { gel.draw(gdrv) }
};


Next point?
Now it begins to be easier. We know the fundamental objects and how they interact. Now we probably have to think about the details...

We have still another big point to consider: my explaination off the game MVC was rather short. We need to complete it in order to have a decent view of what is the system, the game, tthe ame engine and so on.

Anyway, good night, and I hate Hulk.

Emmanuel Deloget

Emmanuel Deloget

 

The new GDnet design

The new design is cool but it broke everything in my journal. I removed the stylesheet (and I guess I have to heavily modify it to get something good enough for your eyes). Too bad. I liked my green theme a lot :/

Oh, I finally saw Casshern. Great movie. I suggest you to give it a look.

Emmanuel Deloget

Emmanuel Deloget

 

The Good, the Bad, and the Design

News
I know you don't care but I received my copy of Dave Eberly's 3D Game Engine Architecture. I'll have a look to his new code.

I use a notebook to type this. The kebord of this notebook is really teh sux0rZZ.

What did we say?
Gosh. Even if I agree with you about the weird LIFO journal structure - it do not fit my current needs and in fact I find it pretty good - I suspect you are able to scroll down and read what I said yesterday. To simplify: the preliminary design I did two days ago has a some important issues that we need to correct.

So : how to resolve this issue?
Our main problem arise because we don't have clearly stated our goals. Remember we are designing a 2D graphic engine. We want to be able to reuse this engine later, maybe in another completely different project. Another thing we want to do is to abstract the rendering code from the game code.

The last sentence is very important. It makes us ask ourselves what is the game code? This is a question we didn't consider yet. Hey! What did I say? There are questions we forgot? Oh! Wait wait wait...

Lets me rephrase the whole thing. We tried to design a graphic engine, we did something which is obvioulsy not correct and we just saw that we forgot at least one question?

Speed vs accuracy
This is always the biggest problem with design. It leads to the failure of small and big projects. As developpers, we want to rapidly code something. We do some design, then we code, and we experience some major problem wit our code. Wee have to do "clever" things to correct the problem - and of course we soon forget the exact meaning of this completely crazy piece of code. We, as coders, often fail because we tried to do things too fast.

So, what do we have to do then?
Let's restart with what is perhaps the most important thing is a software design: the specifications. OMG you'll say! Yes, we forgot them! Yes, we forgot them. Writing the specification or such a large project would take a long time, so we'll only stick with the simple lines : as a component, we want our 2D graphic engine to be open to reusability and therefore should not be tied to a particular game type. It have to be able to draw whatever we want to draw using a simple interface. Of course, it should be fast - while this is a part of the specs, we won't emphasize this point.

You might say that we didn't say anything yet that we haven't previoulsy said. This is not totally true. At a first glance we said that we wanted to create a 2D graphic engine. The we added the draw methods. The particular organisation of these two methods gave us some kind of headache - they were obviously not correct since we wanted to do a graphic engine and not the graphic engine of a particular game.

Let's speak about something else
In order to ease our design we have to think about what we want to do. We want to do a game which uses the graphic engine. This single sentence implies that the game and the graphic engine are two separate things. I previously asked the question "what is the game code?", we did not answer it yet. The game code is a collection of data and algorithm which are used to play the game. They are not related to the rendering code - which is performed by the graphic engine.

On one side, the game code, on the other side, the graphic engine. Or, to be clearer: on one side the game model, on the other side the game view.

Sounds like we should be able to use some design pattern at the higher design level.

Probably. And...?
Nothing else. See you next time? We'll probably speak about the same thing.

Emmanuel Deloget

Emmanuel Deloget

 

The fmx/07 begins tomorrow morning...

... and I think I'll be pretty busy. Well, not tomorrow morning, as there is not much game development related tracks - but I will try to contact a few people, and maybe I'll take a few photos. And I'll visit a few booth. And I'll try to seduce a few girlsAnd I'll try to get loads of free stuff (they gave me a bag yesterday when I went to the press point to get my final accreditation; I suppose I should be able to use that bag to carry all the free stuff I'll find).

The most important talks (as I see it) occurs from Wednesday to Friday. Tuesday is just Not That Bog, although you might get some news posts (I will prefix them using "fmx/07:"). Of course, given that I will spend my time at the fmx, I will have hard time to catch up with the other news, so please be kind - I'll do my best, but I remember that I have only one brain and only two arms. Which is enough, as far as I'm concerned.

Monday still have some interesting stuff - in particular, there are two review talks about WoW and Second Life. Both should talk about content AND gameplay, so that sounds interesting. And then, there is the opening party (sponsored by NVidia). I guess that a lot of people will be there. And the bad thing is that I won't get drunk - because there is just too much too see on Wednesday.

I will try to blog every day or so about what I see, posting some phone numberspictures and other tidbits from the conference. Hope you'll be there to read that [smile].


Emmanuel Deloget

Emmanuel Deloget

 

Text RPG update (post n100 in this journal!!11one)

Nothing much interesting. I was testing StarUML - the open source UML modeler - at work, so I decided to create a class diagram of the RPG rule system (read: what I've implemented so far).

Click on the image for full resolution.



The StarUML C++ reverse engineering tool is one of the best I ever used. The class diagram is rather easy to construct - but the window organisation of StarUML needs a big screen (this is not really a problem since you have a big screen, isn't it?).

I have to test the C++ code generation to see whether it can be used in a production environment.

Anyway, it's an impressive product!

Emmanuel Deloget

Emmanuel Deloget

 

Text RPG rul3z teh big one one one

So far, I've worked about 5/6 hours on the project. The classes I've added today are the following:

ActionTest: this abstract class is used to test if a a particular creature successfully act or not. Here, we make use of the strategy pattern: the algorithm to know wether an action is successful or not is defined by the concrete action. I'va added these needed action tests:

ActionTestSkill will make a skill roll
ActionTestBody will roll an aptitude (body1)
ActionTestMind will roll an aptitude (mind1)
InventoryObjectEquipable: all the equipable objects of the inventory inherits from this base class. It inherits from InventoryObject and is still an abstract class. By the way, I also defined some other inventory object classes:

InventoryObjectMoney which inherit InventoryObject holds a money count.
InventoryObjectWeapon: you guessed it
InventoryObjectArmor: you guessed it too (you are rather clever [smile])
I still need to define some other inventory object types, but these are the most important for the combat system.
OppositionTest I've done the action test, and I also did the oppossition test management - where two creatures confront eeach other. Again, the class is abstract - the plan is to apply the strategy pattern here. So far, I've done some useful derived classes:

OppositionTestSkill: do you want to bargain with an NPC merchant?
OppositeTestBody: arm wresting anyone?
OppositeTestMind: will you resists to the fear aura of this powerfull living dead?
last (currently made) but not least: OppositeTestFight: this one is the base of the fighting system. It does special rolls, modified by the creatures equiped armor and weapons. The combat is mainly resolved using this specilized opposite test.

Speaking of the combat, it may be time to do it now, what do you think?

As for now, the fighting system is pretty evolved. Considering the amount of work I have to do, I wonder if I'm going to be able to get it right the first time.
create the fighting creature list. The player can have allies, and he may fight more than one creature at a time.
sort the creature list (this is an optionnal step, but it can be funny to do some kind of initiative check before the fight)
begin the fight round
for each creature which is not the player
choose action (based on the inventory and on the creature behavior
if action == fight, choose an opponent
resolve action for the player, we have to ask what he wants to do and process his action too
if any creature is dead, remove it from the fighters lists - if the killer is the player, he wins some experience points
repeat until the player or all its ennemies are dead
As you can see, there are some hard parts to implement: how the AI controlled creatures will choose what they want to do or their opponent, how to do the action resolution (if it is a fight, nothing to say; but what about launching a spell, drinking a healing potion or equiping another weapon?)

When I began to think about this project, I thought about implementing a very simple game system (without skills, without those pesky action and opposition tests, and most notably with a very limited fight system - 1 vs 1). I must admit that it was pretty poor, so I've decided to make a correct oen (not very complex but still: it might offer some great gameplay opportunities). Because of this, I decided to cut the most complex feature; the user undo - it is really complex (saving the whole game state?!?!) and doesn't bring anything to the game.

As you can see, I made some cool progress, but I have to handle one of the the hardest part right now. Of course, there is another one comming: the magic system.

I guess I'll have some good time (and comments are welcome, as allways) [smile]


1: hu hu hu. You want to know the games rules, don't you ? [smile]

Emmanuel Deloget

Emmanuel Deloget

 

TCP, UDP, RakNet and reinventing the wheel

In my previous entries, I I spoke to you about a networked application I was creating. I used the TCP/IP protocol, and of course, the associated stream sockets, to build client/server applications. For some reasons, I had the feeling that the solution was limited in a number of ways: first, because of the way winsock works, I had to cheat about the fdset size. Moreover, since I can't know how much client will connect to my application, I was putting my server application in a continuous stress - becasue of the great number of opened sockets (the number of opened sockets in a TCP/IP cserver application is 1 + the number of connected clients). I finnaly decided that TCP was a pain - and I eventually switched to use UDP.

UDP/IP has its own problems though. The big one is that UDP/IP is an unreliable protocol - the packets may not be delivered to the destination application. As a consequence, I have to implement a ACK system - if I do not receive my ACK then I must keep sending the same data again.

UDP/IP is fairly simple to implement, since there is no select() and no accept(). You only need to call recvfrom() in order to receive your messages. sendto() is called to send a message? Instead of using these functions you can connect() your client to the server and then use send() and recv(). Moreover, a lot of network API are using UDP/IP as their base protocol. This is for example the case of RakNet and Hawk NL

HawkNL is a LGPL'ed piece of software - I can't use it for my purpose (GPL and LGPL products are free as in "I'm a virus license"). RakNet is a free product that can be used in a commercial project - although it is very game oriented. This is not very important, the main goal is to have a library that is already written and that has numerous interresting features such as encryption, cross platform support, and so on.

Another solution is to reinvent the wheel again - while this can be entertaining, it is really a bad idea. Consider this feature list:

easy to use C++ interface
cross platform
reliable communication
multithreading support
encryption
compression

Point 1 is OK by definition - the design give it to me. Point 2 is easy to do, but you must write two versions of your core - that encapsulate pure socket management. That's one day of work. Point 3 is also rather easy to obtain - ACK management is not very complex, but since you want it to work transparently (no, you really don't want to have this in the class interface), it has to be very good. One day of work for the implementation and test of this feature. Next point is more complex: multithreading support (for all your target platforms, remember point 2). This point has to be done very carefully and must be heavily tested before you can move on. That's at least one day of work again. Finally, point 5 is done by using an existing library like OpenSSL. Understand, integrate, test. If you are good at this game, you'll need more or less one day of work. Then another day is needed to implement and test compression.

That's at least 5 days of work. One week.

Now, downloading a known, reliable library will probably eat 15 minutes of your time. Designing then writing the C++ interface will need approximately one day, and you'll need another one to integrate the library in your application and to test everything. That's two days. That's 3 days I can spend to something else. For my boss, that's an price cut of nearly 1500 EUR, so he can know buy me a very good PC for the same price, and I'm happy (well... actually he won't do that).

RakNet also implement a lot of other very interresting features (NAT punch-through, multiple ways of handling the data that is sent or received, and so on). In a bunch of words: RakNet provides much more that I would be able to code in the time I'll need to integrate it in my project.

To conclude on this subject, I'm going to use RakNet as my networking API. Building a C++ encapsulation that will suit my needs is trivial (RakNet is already a C++ library, thus I only need to write an adaptor).

Emmanuel Deloget

Emmanuel Deloget

 

Surprise!

Richard announced it - so that's no more a suprise. GameDev.Net, together with NVIDIA and Softimage, proudly present you the new GameDev.Net contest, Shade Your World!

Width this contest, you can win a GeForce 8800 GTX, a license to use SOFTIMAGE|XSI Foundation or the overexcellent new book GPU Gems III (you know, the one with the amazing cover).

Your work: build a shader with NVIDIA FX Composer 2.

So, isn't that a cool surprise?

Emmanuel Deloget

Emmanuel Deloget

 

SQL API reloaded

... I just missed my 1337th post, and this one is the 1338th.

This clicky linky contains additional informations about linux SQL servers.

I seems I said wrong things about PostgreSQL - about its speed to be more precise. The version I tested when I was younger was a v6.something (back in 1999). It was painfull to setup and was slow. But in y2k they released their v7 and they vastly improved the speed of their engine.

I guess I should check the facts instead of saying dumb things :)

So far, PostgreSQL is the DBMS I choose. I am currently creating a simple C++ wrapper over the C API - using the functions I need and only them - in order to encapsulate the libpq calls.

The encapsulation of the calls will allow me to use SQLite as a secondary API. I am not always at home (and I often program on my laptop where I don't want to install too much softwares - mostly because I often use it as a professional tool). SQLite is an easy-to-go solution to avoid the installation of another SQL server.

I am pretty sure that one of the Firefox extension/theme I installed is the cause of my copy/paste problem. If you know anything about the subject, I'll give you a cookie (or a piece of caek if you don't like cookies). Currently, I have thes installed extensions:
Customize Google
PDF Download
Linkification
downTHEMall!
GooglePreview
googlebar
LinkPreview
LinkVisitor
Print Preview
I find them very handy, and I'm not sure I want to remove them - so I hope that my problem don't come from one of them.

I run the Brushed theme (version 0.9.9.5 (I guess that someone will begin to create version numbers with an infinite number of dots in the next few years)), and I find it clean. But I can revert back to the normal theme if it is the source of my problems.

As I think to it, I beleive it is the only difference between the firefox install on my own box and the install on this box. Oh, well, I have a couple of screenshots to do and I'll uninstall ot to see whether the problem is corrected or not.

Emmanuel Deloget

Emmanuel Deloget

 

Some (somewhat crappy) code

Yes. Nothing related to our main activity, but here is some code to answer a question: how to know wether your window is partially/totally overlapped by another window. The code is actually quite - well, how to say that without being blunt? - stupid.


/* getwindowcoverage.c -- version 1, Feb. 15th, 2005

Copyright (C) 2005 Emmanuel Deloget

This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.

Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:

1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.

This license text is based upon the zlib license text.
*/

#include

typedef enum
{
NOCOVERAGE,
PARTIALCOVERAGE,
TOTALCOVERAGE
} WINDOWCOVERAGE;

WINDOWCOVERAGE GetWindowCoverage(HWND toplevel)
{
RECT wrect;
HRGN hrgnwin;
HRGN hrgnwincpy;
HWND hwnd;
HWND prevhwnd;
HRGN otherrgn;
RECT otherrect;
int rgntype;
int rescode;

::GetWindowRect(toplevel, &wrect);
hrgnwin = ::CreateRectRgn(wrect.left, wrect.top, wrect.right, wrect.bottom);
hrgnwincpy = ::CreateRectRgn(wrect.left, wrect.top, wrect.right, wrect.bottom);

prevhwnd = toplevel;
hwnd = ::GetNextWindow(prevhwnd, GW_HWNDPREV);
while (hwnd) {

if (::IsWindowVisible(hwnd)) {
::GetWindowRect(hwnd, &otherrect);
otherrgn = ::CreateRectRgn(otherrect.left, otherrect.top, otherrect.right, otherrect.bottom);
rgntype = ::CombineRgn(hrgnwin, hrgnwin, otherrgn, RGN_DIFF);
::DeleteObject(otherrgn);
if (rgntype == NULLREGION) {
::DeleteObject(hrgnwin);
::DeleteObject(hrgnwincpy);
return TOTALCOVERAGE;
}
}
prevhwnd = hwnd;
hwnd = ::GetNextWindow(prevhwnd, GW_HWNDPREV);
}

if (::EqualRgn(hrgnwin, hrgnwincpy)) {
rescode = NOCOVERAGE;
} else {
rescode = PARTIALCOVERAGE;
}

::DeleteObject(hrgnwin);
::DeleteObject(hrgnwincpy);

return rescode;
}




The pure Win32 code works correctly, but it only tests other top level windows. It means that it is more "is my application hidden by another application" function.

I already gave this code in a past gdnet thread (I believe it was during January).

Comments are welcome :)

Hope you like it ;)

Emmanuel Deloget

Emmanuel Deloget

 

So, I'm in L.A.

Yep. Well, not exactly: I'm in Torrance, in the wonderull Residence Inn near Rodondo Beach (now that you know where to find me, you have no excuse to not come).

My first impression so far?

Well, cars are BIG. And French cheese is made in America. And everything can be cokked in ovens (good thing I have a oven in my room). And (no offense intended) but the only very beautiful girl I've seen so far is French (and has 2 kind kids, and a very strong husband).

But on the overall, I'm impressed. It's quite easy to find anything I've needed so far (but I don't need much). Everyone seems to understand me, despite my horrible English accent - Sneftel knows about it, you can ask him. For the moment, the only thing I would say is that I really enjoy that. The only bad thing is that I must go outside to smoke my cigarettes - but that's not so bad, because as a result I smoke less.

I need to speak about the Residence Inn goodies: every tiny bit of service seems to be free. I have a free braodband intarweb connection, I got a free breakfeast this morning (but I didn't tried to eat eggs or potatoes - you know, we tipically don't eat that so early in France), I can give my grocery list to the hotel staff in the morning and I'll just have to pay for the groceries - not for the delivery. I can swim in the pool from 9 AM to 10 PM, or I can play basketball or tennis. All that come with my $159,00 room (that I don't have to pay, since it's a business trip), packed with a king side bed (any beautiful girl out there? Remember, I'm French... [smile]) a nifty kitchen, a Nintendo-64 enabled TV, and more.

Since Im' here (yesterday), I only had to spend something along the line of $40, mostly to buy food. I gave myself some pleasure by buying some cool Revo sunglasses. I'm also going to buy some Marvel comics - if I can find anything related to their Civil War event.

Of course, the consequence of my trop is that I'm going to enjoy everything, and I'll be less present on GameDev.Net (not sure in fact. I should try to spend more time outside my room). I will also postpone the translations of the blog tickets I wanted to write or translate - and the "SOMETHING" project is delayed a bit, mostly because I forgot to bring it with me [smile].

have a nice day! (and leave a message if you're not far from me)

Emmanuel Deloget

Emmanuel Deloget

 

Small update about the text RPG project state

This is a small update. I hadn't much time to work on the Text RPG project (mostly because I had a lot of stuff to do this week-end), but I have still done something.

To those who are reading this to learn something, I must say that I'm going rather quick here, withour explainations - they will come later, be patient :)

So far, I've created the following classes:

Attribute: handle the creature attributes.
Skill: handle the creature skills. The creatures skills reference an attribute.
Inventory: the creature inventory. It contanis a list of...
InventoryObject: guess what ? Yes, it is. The creature inventory is full of InventoryObject. This is the base class of all the other objects (weapons, armors, keys, money, and so on)
InventoryVisitor: this is an application of the visitor pattern.
CreatureRace: abstract class that gives informations about the creature race (its capabilities, its sub-type, the standard skill and attributes values, the racial skill and attributes modifiers, and so on). It is easy to inherit (a lot of small functions to write) so creating new races is really fun :)
and of course Creature: this is the creature holder class. Any character or monster in the game is a Creature instance (the difference comes from the race and the class [not implemented yet]).
some small utility classes: Dice is a template class that emulates a dice and Dicebag is only used to shuffle the dices (ie seed the randomizer [smile]).


There is something bad with the visitor pattern. It somewhat breaks the open-closed principle (see [RM-1]) because if I add a new InventoryObject type, I need to add a new method in the InventoryVisitor class. Oh, wait. I just had a look to my GoF and found that this is point 3 of the consequences section for the visitor pattern:



I choose the exception rather than the rule and my visitor class is not abstract (the methods does nothing). This is not a problem for me, because in the game system most visitors will only overload one of the base class method (a key is not a weapon, and you can't use your helmet as a spell). But still, I'll have to modify the base visitor class each time I'll want to add a new object type.

As you see, there is not a lot of code (roughly 18 kB, and there is a lot of comments). Nevertheless the game system code is nearly complete (I have a bunch of InventoryObject inherited classes to write, some InventoryVisitor, as well as the action and combat resolution).

If everything goes well, I'll have some time to work on this subject before the end of the week :)

See you later, dudz !

Emmanuel Deloget

Emmanuel Deloget

 

Shhhhhhh! This is a surprise!

We are preparing something for you, dear comrades. And I'm pretty sure you're going to enjoy it. A lot.

Now, that was probably my shortest journal post.

Official announce in a few days... Or before. That's a surprise too.

Emmanuel Deloget

Emmanuel Deloget

  • 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!