|
381
|
Jobs / Collaborations / Re: Monocle Engine: Pseudocode Sketches
|
on: March 10, 2009, 12:59:56 PM
|
I've started another thread on RTTI to avoid derailing this one. If you have time, can you elaborate there? I'm curious since my experience is RTTI allows me to write less code with less repetition, but your experience seems to be the exact opposite  Cheers, Will
|
|
|
|
|
382
|
Developer / Technical / RTTI pros and cons
|
on: March 10, 2009, 12:58:30 PM
|
This came up in Alec's Monocle thread and to avoid derailing that I thought it was worth moving the discussion here. Basically, I've had good experience using reflection/RTTI (in my case, home-made rather than inbuilt) in C++ projects, but I know others haven't. I'm interested to hear what the consensus is, find out if I'm missing some big gotchas, or suggest solutions to problems other people are experiencing. I'd add a poll but I don't know how  If there's technical interest I can outline how my RTTI stuff works as well, but that's going to be a longish post. Cheers, Will
|
|
|
|
|
384
|
Developer / Playtesting / Re: Opera Omnia [Release]
|
on: March 09, 2009, 11:53:45 PM
|
I downloaded this and played it last night - I found I got confused perhaps more than I should, and I had to re-read the briefings several times to figure out what to do. But still, I looked up and it was an hour or so later and I'd got to level 12, so something's definitely going right  I think the core concept is brilliant, but I must admit that only a couple of levels have clicked for me - by which I mean reached the point where I'd internalised enough of the rules to go and set out the solution without trial + error. I do wonder if it would be easier to grasp if the mechanics were discrete rather than continuous (one block of population moved per one bar of years) but then you wouldn't have some of the fiddly but interesting optimisation you have to do on the levels with tight constraints. A minor nitpick: I think the story tips its hand a bit early on - mentioning the Romany people is a bit of a clue as to where things are going/what kind of a place your country might be. Now I just need to finish the game  [edit] Finished now, I did much better today than yesterday. I guess I must be a dyed-in-the-wool coder since level 18 immediately felt like a rounding error trick  That was probably my favourite. Not sure about interpreting the ending, I don't think I would have made the inference others did, but then maybe I'm too thick to draw my own conclusions. I wonder if this was because the protagonist has my name (yay!) and therefore it was hard for me to ascribe genocidal motivations to him? Cheers and thanks for making this, certainly very different to my usual fare! Will
|
|
|
|
|
385
|
Jobs / Collaborations / Re: Monocle Engine: Pseudocode Sketches
|
on: March 09, 2009, 10:47:54 PM
|
I would personally avoid RTTI like the plague.
The use of RTTI isn't critical to my example. You could just as easily declare an enumerated component type or have a static string name in component classes: /// Access an existing facet of this entity template <typename F> inline F* Facet() { return static_cast<F>( Facet( F::StaticClassName() ) ); }
Note that both this and the original version go on top of a method which finds a requested facet by class name/type ID/whatever - the equivalent to Alec's GetComponentByName. That out of the way, can you expand on what don't you like about C++-with-RTTI? I'm such a happy RTTI camper (based on good experiences over several projects) I don't see much of a downside. My only real caveat is that once you have a reflection system it's hard to do without; you need to be quite disciplined about which problems you apply it to, and which you don't really need to. Cheers, Will
|
|
|
|
|
386
|
Jobs / Collaborations / Re: Monocle Engine: Pseudocode Sketches
|
on: March 09, 2009, 02:20:43 PM
|
Hi Alec, Monocle is definitely an idea waiting to happen - I'm looking forward to see how it comes out, and would be happy to offer assistance where possible (my contracts are keeping me pretty busy at the moment). I have a fair bit of PC and console development experience which might be helpful. To wit: Given you're intending (in the long term) to support platforms other than Mac + PC, you'll have to deal with some weaknesses in CPU and cache. I'm a bit wary of the virtual-heavy approach to components you're outlining - it'll work, but it might not scale too well. Something I'm trying at home, which isn't commercially proven but looks promising, is to group components together (as per Muku's suggestion) and hoist the virtual functions out to the group level. This allows you to remain flexible but avoids the performance penalty of the virtual calls. It also makes it very easy to iterate components in an icache and dcache friendly manner. So in my stuff (where a component is called a facet, and a system owns all facets of one type): /** * A system manages all the facets of a particular type in a world. */ struct ISystem : public Noncopyable { public:
/** * \name Creation, destruction. * \{ */
/// Default constructor. inline ISystem( const rtti::IType& type ) : m_type(type), m_world(NULL) {}
/// Empty virtual destructor. virtual ~ISystem() {}
//}
/** * \name System API for concrete implementation. * \{ */
/// Facet factory. Create a new facet of this system's type. virtual IFacet *CreateFacet( const data::PropertyTree::Group& group ) = 0;
/// Facet factory. Destroy the given facet. virtual void DestroyFacet( const IFacet *facet ) = 0;
/// Update the system, called once per frame. virtual void Tick( const Frame& frame ) = 0;
//} /// Access the facet type inline const rtti::IType& FacetType() const { return m_type; }
/// Access the containing world inline World& GetWorld() { SIL_ASSERT(m_world); return *m_world; }
/// Access the containing world (const version) inline const World& GetWorld() const { SIL_ASSERT(m_world); return *m_world; }
private:
/// World needs to set backpointer friend class World;
/// Facet type for this system const rtti::IType& m_type; /// World backpointer World *m_world;
}; // ISystem
/** * Basic concrete system, use this if your facet doesn't need to do anything special. */ template <typename F> class System : public ISystem { public:
/** * \name Creation, destruction. * \{ */
System( Nat count ) : ISystem(rtti::Type<F>()) { SIL_ASSERT( rtti::Type<F>().IsA( rtti::Type<IFacet>() ) ); SIL_VERIFY( m_pool.Create( count ) ); }
//}
/// overrides IFacet *CreateFacet( /* creation parms */ ) { return m_pool.Allocate(); }
void DestroyFacet( const IFacet *facet ) { m_pool.Deallocate( rtti::StaticCast<F>(facet) ); } void Tick( const Frame& frame ) { SIL_FOR_EACH( Pool<F>, m_pool, f ) { // Tick facets, skipping any from entities which were born this frame, or are frozen. const Entity &e = f->GetEntity(); if ( !e.IsFrozen() && !e.IsNewborn() ) { f->Tick( frame ); } } }
private:
/// Facet pool Pool<F> m_pool;
}; // System
This is just an example 'default' system for uninteresting components. The one that does my box2d integration is a bit more complicated but supports the same interface. When you create the engine (or a world) you give it a list of systems with their maximum sizes. The other thing you might want to do is template your GameObject's component lookup - this makes for a nice interface (no casting needed) and unlocks a lot of behind-the-scenes optimisation opportunities if you need them later: /// Access an existing facet of this entity template <typename F> inline F* Facet() { return rtti::StaticCast<F>( Facet( rtti::Type<F>() ) ); }
/// Access an existing facet of this entity (const version) template <typename F> inline const F* Facet() const { return const_cast<Entity*>(this)->Facet<F>(); }
This one calls a generic lookup function with an RTTI object, you could call your string lookup at that point. The nice thing is you can write a specialisation for components you need all the time and store them in members directly. Best of luck with the project, Cheers, Will
|
|
|
|
|
387
|
Developer / Technical / Re: Model-View-Controller discussion
|
on: March 05, 2009, 04:41:53 PM
|
|
One thing that might get lost in reading the Guerrilla article with the MVC in mind is that they split out the const part of their models into resources. I think this is a really good idea - IIRC Tribes did something similar.
It means initialising an entity is cheaper (just find one resource, rather than set all values) and you get a good separation of per-type and per-instance data.
|
|
|
|
|
388
|
Developer / Technical / Re: The Retro-Look of most Indie-Games
|
on: March 05, 2009, 01:49:47 PM
|
I really like the fact that the cockpit compo (and a few other things besides) seem to be defining what I would call the "Amiga 3D" aesthetic as an alternative to pixels, abstract flash, etc. It's great that we might be seeing another style come of age. It's lo-fi (like lots of pixel art) and requires a similar distillation of shape, but it offers a very different palette to work with. Look forward to seeing more stuff in this vein 
|
|
|
|
|
389
|
Developer / Technical / Re: C++ & Low-Level Representations &c.
|
on: March 02, 2009, 07:40:55 PM
|
BTW AFAIK virtual inheritance has virtually no performance impact compared with regular functions nowadays. It only falls short as you cannot (always) inline them.
Do you mean virtual functions, or virtual inheritance? Personally I would avoid the latter as bad design (better to compose objects and inherit interfaces). If you're going to an interview with a games company I would also be careful about what you say regarding the performance of virtual functions. On many platforms, even modern consoles, they are significantly more expensive than regular function calls, and also more expensive than calls through function pointers. With a non-virtual member function, you do something like: push this jump function_address
With a virtual function, you do something like: load vtable this[vtable_offset] load function_address vtable[function_offset] push this jump function_address
The performance issue here is not so much the extra indirection *instructions*, but the fact you'll probably have to load two cache lines, one for the vtable and one for the function code. This can be expensive. In particular: struct IEntity { virtual void Update() = 0; };
// Update entites for ( std::vector<IEntity*>::iterator e = entities.begin(); e != entities.end(); ++e ) { (*e)->Update(); }
can wreck cache coherency if there are lots of different types of entity in the vector. It's not such a big deal on PC because a) PC have huge caches and b) PC games can up their system specs rather than optimise  @Stephen: If I were running an interview, I wouldn't be upset if a candidate didn't know many low-level tricks, provided that a) they were aware of the limits of their knowledge and b) they didn't try to claim that low-level stuff was no longer relevant - if it wasn't, we wouldn't be writing commercial games in C/C++. Algorithmic optimisations are important, but a sprinkling of low level smarts can really help. Good luck with the interview! Will
|
|
|
|
|
390
|
Developer / Technical / Re: The grumpy old programmer room
|
on: March 01, 2009, 08:13:50 PM
|
|
Spent far too much time yesterday trying to cobble together a new server box to replace my aging Shuttle (bad caps in PSU, plus undiagnosed network failure). Ran the full gamut of SATA driver floppies, dodgy cables, DOS BIOS flashing, trying to find the right XP disk to match the CD Key, etc. etc. It did finally work and I got my repo migrated to it.
And worst of all: Just like changing the lightbulb, it's a hardware problem. Not my area innit guv?
|
|
|
|
|
391
|
Developer / Technical / Re: The happy programmer room
|
on: March 01, 2009, 08:10:55 PM
|
I've found myself using unsigned ints a lot recently. I derive a definite pleasure from doing so.
Good stuff! Far too many 'counts of things' are stored in ints, even though you can't have a negative number of whatever thing is being counted.
|
|
|
|
|
392
|
Player / General / Re: memorable cockpits
|
on: February 26, 2009, 11:10:20 AM
|
|
A neat point about Space Hulk was that the small squad monitors were mildly interactive - you could click on them to get that marine to fire a shot IIRC.
Great game - I can still hear the briefing officer: "Brother marines, the hive-mind has blinded our sensors."
|
|
|
|
|
393
|
Player / General / Re: memorable cockpits
|
on: February 26, 2009, 01:53:05 AM
|
Five minutes with some random guessing in Google: is it Infestation?
That's the one! Many thanks, I got stuck thinking of Interphase and couldn't make the leap to another word starting with I.
|
|
|
|
|
394
|
Player / General / Re: Ascendancy
|
on: February 25, 2009, 12:37:21 PM
|
|
Bit easy, but still brilliant. They did another title which was even weirder.
|
|
|
|
|
395
|
Player / General / Re: memorable cockpits
|
on: February 25, 2009, 12:36:34 PM
|
And, keeping on topic: Inferno, the sequel to Epic:
I loved Inferno! I gave my copy away when we emigrated (I used to work with some ex-DID guys) but I still miss it occasionally. More good cockpits: Hardwar (HUD only, but still terrific)  Subwar 2050:  I'm trying to remember the name of an early 3D exploring game where you play an astronaut on some moon or other. Lots of keypads and running out of air IIRC, I remember it being atmospheric, and there were probably giant insects involved. Cheers, Will
|
|
|
|
|
396
|
Community / Cockpit Competition / Re: Pressure
|
on: February 24, 2009, 01:03:44 PM
|
|
Sounds reminiscent of those Amiga/ST/early PC 3D adventure games (Castle Master, Driller etc.) Which is great because they were fantastic - look forward to seeing how this develops.
(There's another one, the name of which escapes me - not from the same people)
|
|
|
|
|
397
|
Player / General / Re: memorable cockpits
|
on: February 24, 2009, 12:34:22 PM
|
|
The Cryo sequel was pretty good too - not as unique as Captain Blood but it had fantastic alien conversations which were all FMV of puppets. Very funny as I recall.
|
|
|
|
|
398
|
Player / General / Re: memorable cockpits
|
on: February 24, 2009, 02:29:47 AM
|
where can i find this!! this a foreign game?
It's I-War. It has Newtonian physics, a great setting, and you get to control a reasonable-sized ship rather than fly a fighter. -- I think it's British, I just happened to find a German screenshot. It is indeed British, it was developed by Particle Systems in Sheffield. I loved the game so much I applied for a job there and ended up lead coder on the sequel. I'm obviously biased, but both are really good fun if you can find a copy, although the sequel is maybe easier to get running. The first game is very much about combat simulation, the second adds in a free-form universe with piracy and other meta-game stuff. One of my contributions to IW2 was the HUD and cockpit code - Matt and Glyn made the nifty cockpit model IIRC.   More information here. Cheers, Will PS: Love the Wing Commander compo icon 
|
|
|
|
|
399
|
Developer / Technical / Re: The happy programmer room
|
on: February 15, 2009, 12:35:37 PM
|
trying to get the camera to display SOMETHING, as one inevitably does at the start of every 3d project... I think that "time to first triangle" is an important development metric, much like "seconds to crate" is for FPS quality  I remember doing an integration at a client site wrestling their camera spec into our camera spec so we could render their view. Nothing visible at all until after a day or so we turned the monitor brightness up and saw a black triangle right in the middle of a very dark blue background!
|
|
|
|
|
400
|
Developer / Technical / Re: The grumpy old programmer room
|
on: February 12, 2009, 05:04:39 PM
|
You can use text project files with more recent versions of CodeWarrior Edit/Preferences/General/IDE Extras/Other Settings "Use text-based projects" This is in Freescale Codewarrior 5.90, I don't remember it being in an earlier (Metroworks) version so YMMV. The text files are XML-formatted.
|
|
|
|
|