Immediate messages

Feb 2, 2008 at 11:40 AM
This is the discussion for issues: Immediate messages
Feb 2, 2008 at 11:42 AM
The message system is not meant for this type of interaction, and the overhead applied would not be acceptable. Why do you not simply queue the entities directly you have full access to all of them?
Coordinator
Feb 2, 2008 at 5:21 PM
Edited Feb 2, 2008 at 5:24 PM
That might work in the case of the camera which is attached to a player, but it will not work for everything. The overhead should be insanely small. I've used systems with immediate messages, and as I've stated engines like the Unreal3 engines use this, you can send hundreds of messages per frame with little overhead. It is simply that some messages do not go to a queue, they go directly to the specified interface, and fill the information in. There is no need to pass the message back because the information is by reference, so the original sender can simply access the variables it just sent.

Imagine if I wanted to base player movement on the scene's main camera. That player may not have a reference or variable for that camera, so it would send the "GetForward" message to the camera interface requesting the scene's camera information, and it would in turn recieve it.
Feb 2, 2008 at 5:46 PM
The problem I see is defining the end points for the messages. Right now the message system is set up so that neither sender nor receiver care how sent the message and who receives the message. Further, there can be many senders and many receivers of a particular type of message.

I agree with Sturm that the message system is just not designed for this. If this functionality is required, then I believe we would be best off designing a separate "query" system to handle this. Messages are one-way interactions. Some state of a system changes, so it broadcasts that change in the event that another system needs to know about it. Queries are inheritly two-way interactions, and can be done in two ways:

  • Assign one specific end-point for a specific query type and pass around a structure to fill in, or
  • Assign multiple end-points, and return a List<> of responses.

You can create an IQueriable interface, implemented by all classes that can be queried for some data. Then create a QueryManager of some sort and register IQueriable instances along with query types.


One thing I've noticed is that all of your examples stem from player or world interactions. Is there some way we can just design the SceneManager to give us this information?
Feb 2, 2008 at 5:46 PM
You do have a reference to everything, if you haven't we should connsider including this information in the scenemanger.

So if you would like to do your scenario then:

    public class Player
    {
        ...
 
        public void override Update(GameTime gameTime)
        {
            this.Position = this.Game.Scene.ActiveCamera.Position * this.Game.Scene.Entities["Explostion"].Forward;
        }
    }

Or at least something similar to this.
Feb 2, 2008 at 5:57 PM
Yeah, that's pretty much what I was envisioning, minus the referencing of entites by strings. :)

Seriously, would we need anything more than just the ability to query scene nodes by name and/or type? At initialization, query for the camera (by name or type) and store a reference to it.
Feb 2, 2008 at 6:10 PM
As a scene can be rendered multiple times using different cameras, I can't see that you could simply query it at constructiona and safe the reference, also a camera could change during gameplay. Having a Active/Player camera in the root on either scene or game.

Year year, but strings make so much better understandable, but could have used EntityIdentifiers.Explosion instead ;)
Feb 2, 2008 at 6:47 PM
For well-defined things like an active camera, then sure.

I would just make it best practice to query the first time then save the reference for general entities, if possible. You could even have a LeavingScene scent on entities, so objects holding references to them know when the reference is being invalidated.
Coordinator
Feb 3, 2008 at 4:43 AM
Edited Feb 3, 2008 at 4:57 AM
I guess I am very confused. If we're going to be able to get whatever information we want from a scene manager, at any time, why do we have messaging? If the input interface is simply inside of a scene manager then why don't I just reference it directly. If the camera system is part of the scene manager why don't I just reference it directly? How about physics, animation? Why send messages at all? Seriously, why not just have functions that recieve information directly from other interfaces?

We send messages to keep the code clutter to a minimum. I shouldn't have to worry about connecting 20 different systems to the scene manager when I can simply have them communicate through messages. This also lets each system self-manage itself. If we don't require camera messages to go through the camera system then we literally have no control of how the engine treats cameras. If we decided we wanted all cameras to perform a specific action then we would have to re-write the camera class or all cameras individually, when we could just have the camera system handle things how we want.

I don't see why this is so difficult to understand.

1.) Register every interface with the engine.
2.) When sending a message, specify which interface that message is handled by.
3.) Specify the sending method (immediate, or queued).

If you guys would like I'll make an extensive lists of things I cannot do without immediate messages. This is vital that we figure this out now, because I strongly feel the message system is somewhat pointless if we cannot send a message and then use information with it. In fact, if we send a message, we then have no idea when the message actually takes place.

What if I want to send a message from the camera system to change the screen dimensions, in the graphics system, then immediately after that I tell the camera to recalculate the field-of-view due to a new resolution? The new field-of-view would be entirely worthless because the message will not have occured yet. In fact, I'd have to go so far as to create a message in the camera system so that the graphics system, upon recieving a message to change the screen dimensions could tell the camera system to resize the field-of-view. Of course, that message will be difficult if we don't have a camera system, because we're currently saying the scene manager will have direct access to the cameras. And what if I wanted to resize the screen or change resolutions without changing the field-of-view? It'd be insanely easy with immediate messaging because I could send the message to resize the screen, and then simply do nothing after that. But if the graphics system is supposed to act on the message (which it would without immediate messaging), then I'd have no choice. Additionally, I may want specific camera types to change the field-of-view, and not others.

This is one a huge series of things I could list out given the type. Sure I could rethink everything I'm used to with game programming, but I think that is the exact opposite of what people want with an engine, they should be able to do what they need very easily, and what I'm describing is far from it. What I just described was:

1.) Sending a message to graphics system
2.) Wait a frame or more
3.) Graphics system sends a message to camera system
4.) Wait a frame or more
5.) Camera system has to have code to recieve the message to change field-of-view
And we couldn't have done anything that required the changes to the field-of-view during those frames, and would have to have mechanisms to not do those changes that would require the new field-of-view, and to be intelligent about how to do this transistion.

OR

1.) Sending a message to the graphics system
2.) Change field-of-view. (We could check if message returned false, which may indicate a screen change didn't happen properly).

.....your call.

Finally, I feel that it will very difficult to know the order of messages if they're all in a queue. What if I need to change the resolution, then field of view, then do 3 other actions in order, or the game will crash? I'd have to set up messages or functions that would all in turn call those other actions. This means a rediculous amount of thought to something so simple. With immediate messages I could simple do

Action 1, then 2, then 3, then 4, then 5. If my messages aren't immediate then how do I know some other system hasn't changed along the way? I don't, things do change, I'd expect things to change. If I can send and recieve info immediately I don't have that concern.

I guess my biggest question is why are we avoiding creating something so simple. It should be very easy for me to tell a message that it is handled by the input interface.

SendMessage( MessageType, InterfaceType.Input ); // done

It would require only a switch statement to send the enumerated type (input in this case), and as you guys probably know, and switch is very efficient, as they're simple memory offsets after being compiled (assembly anyone?).
Feb 3, 2008 at 11:32 AM


LordIkon wrote:
I guess I am very confused. If we're going to be able to get whatever information we want from a scene manager, at any time, why do we have messaging? If the input interface is simply inside of a scene manager then why don't I just reference it directly. If the camera system is part of the scene manager why don't I just reference it directly? How about physics, animation? Why send messages at all? Seriously, why not just have functions that recieve information directly from other interfaces?

We send messages to keep the code clutter to a minimum. I shouldn't have to worry about connecting 20 different systems to the scene manager when I can simply have them communicate through messages. This also lets each system self-manage itself. If we don't require camera messages to go through the camera system then we literally have no control of how the engine treats cameras. If we decided we wanted all cameras to perform a specific action then we would have to re-write the camera class or all cameras individually, when we could just have the camera system handle things how we want.


No we don't send message to reduce cludder, we send messages because we do not know which systems need the information. Messages reduces the interdepencency between systems, and allow for a more flexible way of communicating.


LordIkon wrote:
I don't see why this is so difficult to understand.

1.) Register every interface with the engine.
2.) When sending a message, specify which interface that message is handled by.
3.) Specify the sending method (immediate, or queued).


It's not difficult to understand, it's just not needed, or would be expensive to implement compared to directly invoking the reciever.


LordIkon wrote:
If you guys would like I'll make an extensive lists of things I cannot do without immediate messages. This is vital that we figure this out now, because I strongly feel the message system is somewhat pointless if we cannot send a message and then use information with it. In fact, if we send a message, we then have no idea when the message actually takes place.


Not a list, we need the scenarios. It's not pointless, it works perfectly in the current implementation. There are some issues which we need to extend the message system in order to resolve, like adding priority.


LordIkon wrote:
What if I want to send a message from the camera system to change the screen dimensions, in the graphics system, then immediately after that I tell the camera to recalculate the field-of-view due to a new resolution? The new field-of-view would be entirely worthless because the message will not have occured yet. In fact, I'd have to go so far as to create a message in the camera system so that the graphics system, upon recieving a message to change the screen dimensions could tell the camera system to resize the field-of-view. Of course, that message will be difficult if we don't have a camera system, because we're currently saying the scene manager will have direct access to the cameras. And what if I wanted to resize the screen or change resolutions without changing the field-of-view? It'd be insanely easy with immediate messaging because I could send the message to resize the screen, and then simply do nothing after that. But if the graphics system is supposed to act on the message (which it would without immediate messaging), then I'd have no choice. Additionally, I may want specific camera types to change the field-of-view, and not others.


Well the scenario outlined here is not really relevant as there are many more issues you need to consider when doing this, chaging the FoV during a update call is not something you should ever do, as you might have one half of the entities using the old view and the other the new view.


LordIkon wrote:
This is one a huge series of things I could list out given the type. Sure I could rethink everything I'm used to with game programming, but I think that is the exact opposite of what people want with an engine, they should be able to do what they need very easily, and what I'm describing is far from it. What I just described was:

1.) Sending a message to graphics system
2.) Wait a frame or more
3.) Graphics system sends a message to camera system
4.) Wait a frame or more
5.) Camera system has to have code to recieve the message to change field-of-view
And we couldn't have done anything that required the changes to the field-of-view during those frames, and would have to have mechanisms to not do those changes that would require the new field-of-view, and to be intelligent about how to do this transistion.

OR

1.) Sending a message to the graphics system
2.) Change field-of-view. (We could check if message returned false, which may indicate a screen change didn't happen properly).

.....your call.


Doing this is much worse that you think no matter which approach you are choosing, currently the engine does not handle this at all. In order to do it we most likely need to implement a pre/post update where this can be resolved. But let's do the above without the use of any messages:

protected void UpdateCore(GameTime gameTime)
    {
        this.Game.GraphicsDevice.RenderState.Resolution = new Vector2(640, 480); // Or somthing like this
        this.CalculateFoV();
    } 


LordIkon wrote:
Finally, I feel that it will very difficult to know the order of messages if they're all in a queue. What if I need to change the resolution, then field of view, then do 3 other actions in order, or the game will crash? I'd have to set up messages or functions that would all in turn call those other actions. This means a rediculous amount of thought to something so simple. With immediate messages I could simple do

Action 1, then 2, then 3, then 4, then 5. If my messages aren't immediate then how do I know some other system hasn't changed along the way? I don't, things do change, I'd expect things to change. If I can send and recieve info immediately I don't have that concern.

I guess my biggest question is why are we avoiding creating something so simple. It should be very easy for me to tell a message that it is handled by the input interface.

SendMessage( MessageType, InterfaceType.Input ); // done


Yes with our current messages you do not know the order of the messages, and that's a good thing. Yes it would be very easy to do, but you can do the same using direct access so I do not see the value.


LordIkon wrote:
It would require only a switch statement to send the enumerated type (input in this case), and as you guys probably know, and switch is very efficient, as they're simple memory offsets after being compiled (assembly anyone?).


Well a switch is not going to be an option as you need custom values as well. Using int might be possible but most likely you would want to limit it to the type, and in this case the switch isn't anyway near that implementation. I'm actually not even sure that .net does this even for enum/ints, maybe Shaw knows?

The main thing here is that we need some valid scenarios in order to do this, until now I haven't seen anything that would require a system like that.
Coordinator
Feb 3, 2008 at 4:44 PM
Ok, then in the many many situations I know I would use immediate messages, I will instead not be using messages whatsoever. We don't need immediate messaging then I am going to use dependancies and functions. I see no reason to completely work around every situation in which immediate messages would work, and in fact I'm completely against it because this decision will make developers job much more difficult.

I also disagree about the performance cost of directing messages to a system. All you are doing is routing a message based on an enum, what is the problem?

Not knowing the order of the messages is not a good thing. In many situations I need to know the order of my messages.

Here's the deal:
As a developer, I need the use for immediate transfer of information, just like other engines do.

If the above requirement cannot be met, I will not be using messages in those situations, and will be causing interdependancies. Plain and simple. We shouldn't have to work AROUND the messaging system, but if you would prefer it that way you can have it.

Changing the FOV during gameplay IS indeed valid, I do it everyday at work, different cameras can and will have different FOVs, and developers may want to test them during runtime, while the actual changing of FOV on the rendering cam may not happen during an update loop, all changes to the FOV can be used as if it had, and in between updates the rendering cam can update itself. Using immediate messages IS valid, I use them everyday, and I can also attest that the performance between queue and immediate messages is in fact of NO difference. The mechanism that routes queued messages is the same as immediate, immediate just doesn't wait in a queue.
Feb 3, 2008 at 6:32 PM

LordIkon wrote:
Ok, then in the many many situations I know I would use immediate messages, I will instead not be using messages whatsoever. We don't need immediate messaging then I am going to use dependancies and functions. I see no reason to completely work around every situation in which immediate messages would work, and in fact I'm completely against it because this decision will make developers job much more difficult.


Messages are still valid in many situations, input/sound/system messages, and really can't see that it will make developer scenarios much more difficult, can you provide some scenarios which describe this?


LordIkon wrote:
I also disagree about the performance cost of directing messages to a system. All you are doing is routing a message based on an enum, what is the problem?


The performance can be about the same, though it won't be possible to use enums you need to at least use integers, if not based on type.


LordIkon wrote:
Not knowing the order of the messages is not a good thing. In many situations I need to know the order of my messages.


Can you define the scenarios where this is needed? We are going to need a priority on the mesages, but I haven't fully got my head through that yet. But there is still no order of messages


LordIkon wrote:
Here's the deal:
As a developer, I need the use for immediate transfer of information, just like other engines do.

If the above requirement cannot be met, I will not be using messages in those situations, and will be causing interdependancies. Plain and simple. We shouldn't have to work AROUND the messaging system, but if you would prefer it that way you can have it.


I need a scenario that defines this need, just stating it isn't enough. The problem of interdependencies is just as valid using messages, it's just hidden and broken interdependencies might not be visible right away. So please provide some scenarios which defines these requirements.


LordIkon wrote:
Changing the FOV during gameplay IS indeed valid, I do it everyday at work, different cameras can and will have different FOVs, and developers may want to test them during runtime, while the actual changing of FOV on the rendering cam may not happen during an update loop, all changes to the FOV can be used as if it had, and in between updates the rendering cam can update itself. Using immediate messages IS valid, I use them everyday, and I can also attest that the performance between queue and immediate messages is in fact of NO difference. The mechanism that routes queued messages is the same as immediate, immediate just doesn't wait in a queue.


Yes I know that changing the FoV is a valid scenario, your example on doing it was wrong. Lets assume you need to change the fov during an update, lets further assume you do this on a update just before a draw, if you now update halfway through half the entities you might end up having some of the entities not being visible on the screen as they were updated using the old camera fov not the new. So if you do change something which changes Fov you bacially need to redo your update of the entities to be sure they are now using the new fov.
Coordinator
Feb 3, 2008 at 8:52 PM
I would imagine messages having a type, as well as an interface destination.
Feb 3, 2008 at 10:19 PM
There are bigger issues here. Quite frankly, a lot of current game development paradigms are broken. Going forward, we need to design game technology that is parallel instead of sequential. Sequential function calls for information passing as not going to be sufficient in the future. That's why we need generic message passing that is asynchronous for inter-module communication. Course-grained multi-threading isn't sufficient and individual modules may span multiple threads.
Feb 3, 2008 at 11:43 PM
Yes currently many "game" development paradims are not working, but then again we are not building a game. In my mind there will be a game OM which will almost just be a procedural way of looking at the world, the engine will handle all the mess with cross thread serialization/inter-module communication, but on the "game" level you would just write the event code needed for the game, similar to what the WinForms layer does.
Feb 4, 2008 at 12:14 AM
That's what I'm saying. At the engine level we need to get away from this sequential way of thinking. Modules need to maintain and broadcast state. Having lots of querying just results in bubbles in concurrent execution. When a module has to start using locks for everything it does because a query may come in from another thread and interact with the shared state data, your multi-threaded performance crumbles and your engine falls to its knees.

I firmly believe we need to innovate here. If we just stick with the tried and true game development ideals, then what's the point of this project?

But this is getting off-topic here. We should start a new thread for discussion on how multi-threading fits into the engine.
Coordinator
Feb 4, 2008 at 2:01 PM
I use immediate message all the time, in game, not in engine, and that is how I know I will end up needing it. But I am sick of arguing this point, so when it comes time that I do end up needing it, we can implement it then. I just wanted to save us the hassle and get it out the way before we start making a game.
Feb 4, 2008 at 8:23 PM
We will only implement what we have valid scenarios for, so you only need to provide these and we'll implement it. We are only arguing that the presented scenarios aren't valid and can be don "much" more efficiently in a different way.

So present the scenarios and we'll surely implement this.
Coordinator
Feb 4, 2008 at 10:57 PM
I want to create a camera that makes sure nothing comes between the player and itself. Here's how it would need to be done (I've done it this way many times).

1.) Cast a ray from the player/target to the camera.
2.) If the ray hit something, move the camera to the point of intersection.
3.) Sometime during that same frame check the camera frustum against the terrain to make sure it isn't below the terrain. If it is below, move it up so that it isn't.

Pretty simple stuff really. However, this simple concept requires communication between the player, camera, physics system (for ray casts against physics objects), and terrain system (for height checking against heightfield). Here is how I need to be able to do it:

1.) Send a ray message, passing the source and destination points. Ray message fills in the point of intersection with a physics object (if there is one), and the type of physics object that was hit.
2.) Move the camera to that point in space. No message required here, as we're in the camera class.
3.) From our new point in space that we've moved to, we need to find the points that are represented by the frustum. Again, no message here, the camera should know about its own frustum.
4.) Using our frustum points in relation to the intersection point we moved to, we check each point against the heightmap. This requires sending two messages to the terrain system. The message would be passed with the 2D point (x, z), and the terrain system would fill in the Y-axis point.
5.) I would take the two points, and if either were below the terrain, I'd move the camera up the height of the highest of the two points. No message needed here.
Feb 4, 2008 at 11:01 PM
Except your forgetting that the SceneManager and Physics systems are inheritly tied together by design. The SceneManager (via the Physics system) will support direct ray (and some sort of frustum) queries which can be accessed directly from the camera class.

There should be no messages in this example. The camera has a well-defined internal position, as well as access to its target's position (arbitrary scene node, not necessarily a player).
Feb 4, 2008 at 11:03 PM
Remember that messaging is for generic inter-module communication. Interactions that fall completely within one system (in this case, SceneManager) can do whatever it wants as long as its consistent. The only exception to this rule is the SceneManager/Physics communication. Although this isn't really that much of an exception as the SceneManager and Physics systems are really one-in-the-same when you think about it.
Coordinator
Feb 4, 2008 at 11:06 PM
Edited Feb 4, 2008 at 11:07 PM
If every scenario in which I'd normally use a message if invalid because the systems are tied together, then I would say we have too many systems tied together.

This is rediculous. You're telling me the player, camera, physics, terrain, and scene system are all directly dependant on each other and none of them should use messages to communicate information? I'm probably missing some other systems too.

If everything exists within a scene, EVERYTHING has access to the physics, terrain, and camera information. This is a huge OO violation in my opinion.
Coordinator
Feb 4, 2008 at 11:10 PM
I've got a better idea, rather than me argue why we need immediate messages, I'd like you guys to give me examples why we need any messaging whatsoever. Everytime I've said "Hey, this would be a good place for a message", I get, "No, just use direct function calls". Input is the only system I believe messages are good for at this point, because of abstact virtual key actions we can do later.
Feb 5, 2008 at 4:21 AM
I'm not arguing that we shouldn't use messages, we need messages. I just have a issue with the imidiate messages and can't see why these are needed. For me (and I guess Shaw too) these messages would be much more efficiently replaced with direct invocation. All we are asking are that you provide some scenarios where imidiate messages are needed, as you've seem to have been using these in the past.

But as of scenarios for the message system:
  • Input System
    • As you described above the input system is a good example of this.
  • Physics System
    • There might be good scenarios for sending messages to the Physics engine, as it runs out of thread using messages might be the only performant way of communicating, Shaw any ideas/comments?
  • Scripting System
    • The scripting system will need to react on various messages, and instead of hooking everything in everything messages provides a good way of communicating.
  • Networking System
    • The networking system needs to send messages to everyone, so messages are the only good way of doing this. This could also be status information for lag/through put/etc
  • System Level
    • There are also system level messages, such as pause/quit/screenshot/etc which needs to send a message before being activated

There a prob lot more, but I do not currently have any valid scenarios to support these.

The current messaging system is not complete at this time, we certainly lack some functionallity; like priority, and message merging: These will be added once we get the scenarios for it.
Coordinator
Feb 5, 2008 at 4:51 AM
Direct invocation, or functions between systems is the exact reason we created messages. If you guys would've told me we'd just be calling functions in most of these cases I would've opted out of a messaging system. I don't agree that we should have half the systems using messages, and others not. To me it is all or nothing except in extreme cases like the physics engine for collisions.

How are we supposed to explain to the developer, these 7 components use messages, these 4 components don't use messages, and these 5 components use some messages, but of the ones that use messages you cannot use half of the functionality in those components unless you use direct invocation because you will need to wait a frame.

I like the sound of this better: We have 25 components, and while many have direct connections for performance reasons, EVERY one of them has the option of immediate messages so that you may access information through it at any time AS IF you had a direct connection to it.

So far here is the stretch you guys have been making on the camera system. Cameras are connected to entities, entities are part of a scene, a scene is part of the scene manager, and the scene manager has a connection to the physics system. IF all of things end up being true after I re-vamp the camera system, then I could check rays between the camera and physics entities without a message. However, what if I disconnect cameras from that chain of dependencies? What if something else in someone else's game needs to cast a ray from a point to another point and get results? What if they're not connected to the scene manager somehow?

Why are we purposely avoiding making the engine easier to use? I don't even care anymore about the performance impact of it, for god sakes just give them the option of doing something, even if the performance is worse. For certain things, like a ray cast, that will happen once or twice per frame, I don't care if the performance is slower. For things that occur 100 times per frame that is a different story, something like that might go through a queue or just be connected directly.

I will try to post one example per day that requires the use of immediate messages. The argument that casting a ray between the camera and physics system will work because of a chain of dependencies is a weak one. I planned on having the camera system independant of the scene manager, and the only thing the scene manager would get from it is a pointer to the current camera, everything else should be managed by the camera system. Ray casts may not have to go through the camera system, but if they did, and it was independant, how does it work without immediate messages? Again, this is just one example, I will post more.
Feb 5, 2008 at 6:23 AM

LordIkon wrote:
Direct invocation, or functions between systems is the exact reason we created messages. If you guys would've told me we'd just be calling functions in most of these cases I would've opted out of a messaging system. I don't agree that we should have half the systems using messages, and others not. To me it is all or nothing except in extreme cases like the physics engine for collisions.


We didn't implement the messaging system to replace direct invocation, or at least that wasn't my intension for it. The message system is meant to transfer state change information one to many endpoint where the endpoints would not care about where the message came from, just as the sender wouldn't care about who was listening. This gives you the ability to do some advanced scenarios, like macros and scripting, without doing deep interdependent code.


LordIkon wrote:
How are we supposed to explain to the developer, these 7 components use messages, these 4 components don't use messages, and these 5 components use some messages, but of the ones that use messages you cannot use half of the functionality in those components unless you use direct invocation because you will need to wait a frame.

I like the sound of this better: We have 25 components, and while many have direct connections for performance reasons, EVERY one of them has the option of immediate messages so that you may access information through it at any time AS IF you had a direct connection to it.


I wouldn't describe it like that, besides you have to keep in mind as well that there are two types of developers, game and engine. As game developers live in a scripting world, most of these terms will be unfamiliar to them, I know a lot of script devs who do not even understand OO. Engine developers on the other hand should easily grasp the model and be able to see how the messaging system is set up.


LordIkon wrote:
So far here is the stretch you guys have been making on the camera system. Cameras are connected to entities, entities are part of a scene, a scene is part of the scene manager, and the scene manager has a connection to the physics system. IF all of things end up being true after I re-vamp the camera system, then I could check rays between the camera and physics entities without a message. However, what if I disconnect cameras from that chain of dependencies? What if something else in someone else's game needs to cast a ray from a point to another point and get results? What if they're not connected to the scene manager somehow?


You do not want to do that, removing the cameras from the scene also removes the option of having cameras attached to entities, which is the initial design. But lets assume that cameras were detached, or we only surfaced a single player camera. Now on every frame you need to access the current player character in order to position the camera properly, so you would just do this.Game.Scene.Entities[EntityIndex.Player].Position But if you removed the game reference from the Camera as well how would you get the entity? Well you wouldn't. That would be the same as not registering the camera for messaging in the first place, at one point there has to be a reference one way or another.


LordIkon wrote:
Why are we purposely avoiding making the engine easier to use? I don't even care anymore about the performance impact of it, for god sakes just give them the option of doing something, even if the performance is worse. For certain things, like a ray cast, that will happen once or twice per frame, I don't care if the performance is slower. For things that occur 100 times per frame that is a different story, something like that might go through a queue or just be connected directly.


That's the problem we do not think it gets easier to use. You are just introducing yet another way of doing what's already possible. Using property based programming is a know and accepted programming model, if that's difficult for the developers they most likely shouldn't be looking at engine code.

The message system is accessed 100's of times per frame, so any performance hit here is quite devastating. We already did a substantial work on getting the most out of the current messaging system both in terms of speed and memory footprint.


LordIkon wrote:
I will try to post one example per day that requires the use of immediate messages. The argument that casting a ray between the camera and physics system will work because of a chain of dependencies is a weak one. I planned on having the camera system independant of the scene manager, and the only thing the scene manager would get from it is a pointer to the current camera, everything else should be managed by the camera system. Ray casts may not have to go through the camera system, but if they did, and it was independant, how does it work without immediate messages? Again, this is just one example, I will post more.


You do not need to post one a day just post 2 or 3 scenarios where intermediate messages can't be solved using direct invocation or the current messaging system, that would be fine.

But as I said removing camera from the scene is not a good solution, unless we can come up with a way of attaching these to entities.
Coordinator
Feb 5, 2008 at 1:32 PM
It comes down to the fact that when developers create two systems, that even have the slightest chance of transferring information that cannot be delayed a frame, that we'd be forcing them to connect the systems together and make them dependant. I don't believe that is good practice.

I still don't understand the performance argument. How difficult is it to route a message to a specific registered interface? Lets assume for a moment that there were little to no performance impact, what now is stopping us from using this messaging interface.

I'm starting to wonder if I can even work on this project anymore. I work on games all day at work, understand exactly how they work, then I get on here to have everyone tell me that everything I do at my professional job is wrong, and shouldn't be done that way, and is inefficient. Frankly it is getting old. I know what is working, and why it is important to me, apparently I'm just bad at communicating this to others.
Feb 5, 2008 at 3:00 PM


LordIkon wrote:
It comes down to the fact that when developers create two systems, that even have the slightest chance of transferring information that cannot be delayed a frame, that we'd be forcing them to connect the systems together and make them dependant. I don't believe that is good practice.


Well they are dependant so why is that an issue? You wouldn't remove the dependancy by introducing a messaging system here. A needs B and isn't not possible to remove that dependancy.


LordIkon wrote:
I still don't understand the performance argument. How difficult is it to route a message to a specific registered interface? Lets assume for a moment that there were little to no performance impact, what now is stopping us from using this messaging interface.


Ok let's just stop arguing about performance and say that they are the same, then you are still introducing a new system to accomplish what is already possible, so it adds no real value here.


LordIkon wrote:
I'm starting to wonder if I can even work on this project anymore.


I'm sorry to hear that you feel that you have to leave the project. If anyone should leave it should be me, as I'm only a dev on the project, and it's bacially me who do the most objections.


LordIkon wrote:
I work on games all day at work, understand exactly how they work, then I get on here to have everyone tell me that everything I do at my professional job is wrong, and shouldn't be done that way, and is inefficient. Frankly it is getting old. I know what is working, and why it is important to me, apparently I'm just bad at communicating this to others.


Since you work with this every day, can't you take some of the scenarios you are covering, doesn't have to be specific, and give them to us so we can understand the need for such a system? The problem is that most of us, at least me, aren't working on games. I for one am working on multitier enterprise platforms as a dev, so I certainly do not have the game perspective, though I do know a little about threads, perf and creating frameworks. But my experience might not fit in a game box. I'm here to learn, so by all means I'm not saying I'm right in this sense, but you do need to prove me wrong, before I simply accept it.
Feb 5, 2008 at 5:27 PM
I just don't understand where this loss of functionality mentality is coming from. Through out this whole project, my primary goal has been innovation and forward thinking. I design and build according to what is most likely to work well in the future, given our current knowledge of hardware/software evolution. My goal is not to duplicate the current state of game technology, but rather analyze the trends and see what will be the most scalable solution 1-3 years down the road. What's the point of having new projects like this one if all you're going to be doing is the same old thing?

The future is concurrency. I don't think there's much that can be said to counter that argument. Current CMOS processes have been pushed about as far as they can go, and we cannot increase clock rates or instruction-level parallelism. So we're going multi-core. Soon we'll hit many-core. The new Moore's law is the number of cores will double every 18-24 months. Intel already has an 8-core prototype (Nehelem) that will probably be out by the end of the year. To embrace this trend, game technology must evolve to be highly scalable, from 1 to n cores. To how do we accomplish this? It's hard to say, we can only do our best to innovate new designs. But one statement has been repeated many times and I feel it is 100% true: "locking semantics have got to go."

How does this work into our messaging fiasco? We're blessed with the task of creating scalable, parallel solutions with inheritly sequential languages. C# is getting a little better at potential future concurrency features, but its still a sequential language at its core. So, we need to distribute our game processing over n cores. In the past, there have been two main approaches: course-grained threading and fine-grained threading. With course-grained threading, each system gets its own thread. This works, but you have the issue of parallel data flow and you're only as scalable as the number of independent systems you have in your engine. On the other hand, fine-grained threading lets everything be a thread. Now, you have serious data synchronization problems and severe overhead on 1-2 core machines. What seems to be a good solution is to mix these two concepts like Valve has done recently with the Source engine. One implementation of this concept would be to let each system create atomic "tasks" that are scheduled independently and assigned to a free core. The trick is to make these tasks truly atomic which is a lot easier said than done. On a 1 core machine, these tasks will execute sequentially with minimal overhead. You just one processing thread that contains the entire queue. On a 4 core machine, you have 4 processing threads and tasks are scheduling similar to a CPU scheduling algorithm in an OS. This is a pretty elegant solution, really, but you're still left with a huge problem: data synchronization.

At the end of the day, this problem boils down to: how do we let tasks share information? Global data sections are an option, but there's no synchronization here. You can add in locks, but now your concurrent tasks are spending most of their time waiting on locks and rendering themselves back into sequential execution. (Remember: locking semantics have got to go!) Or, you could copy shared data and merge it back together after the tasks process themselves. This is the method used by functional languages and works well for them (no global state!) but copying can be inefficient in the general case and horribly inefficient when you have large data sets. Yet, at the end of the day this is probably the better solution of the two.

Now, here's the kicker for the messaging system: who owns a task's state? Does a particular task own it's own state? Does it's parent system (if there is one) own it's state? Is there a global state repository (again, implying the deaded locks of death)? Further, how do other tasks get access to another task's state (here's why immediate messaging with immediate returns may not be ideal)? Do they say, "hey task #14, I need the state of keyboard button F"? Task #14 would be happy to oblige, but unfortunately it's currently querying for a gamepad input so the caller's going to have to wait until it gets a free moment to respond to the state query. Sure, it can do it in parallel with locks of death, but then you're forcing sequential execution between these two tasks, which is what we wanted to avoid in the first place. Unless you only cared about last frame's state which could be cached free of locks. But then, what's the point of doing a real-time query if you don't need the latest and greatest state information?

So, what about a concurrent solution that that doesn't require caller or callee locks? Hrm, what's the catch? You pay a little up-front cost of extra memory, but you get uninterrupted concurrency. A fair trade, I'd say. What is this solution? Asynchronous messaging. When a task is executing, it doesn't care what the rest of the system is doing. It has state information for everything it cares about, and goes along its merry way. When it's done, it broadcasts its internal state changes to the system. Further, while it waits for its next iteration for the next frame, its busy listening for other broadcasts from other tasks so it can collect the state information it needs for the next frame. The only catch here is what happens when a state broadcast comes in mid-task. The solution here is simple as well, in theory. You can maintain two state blocks. While executing, you act on the current state block and store state messages into the future state block. After executing, you swap the future to the current and start collecting additional state in to the current state buffer. Rinse and repeat. A little overhead for very scalable concurrency.

Is this the best solution to the problems of the future? Probably not. It feels much more scalable than current solutions for present-day problems, though. Also, we're quite limited by current sequential languages. No-one here is saying what's going on today in the games industry is wrong. All I'm saying is that we need to assess the trends for the future of hardware/software and decide how best to meet the challenges faced there. Remember that current game technology is based on 3-4 year-old designs when single-cores were still the norm. Just because something works well today doesn't mean it will work well in the future. Could it work well in the future? Sure! Only time will tell. But we can still plan for the future and do what we feel is best instead of just doing what everyone else is doing then coming to the realization that our system doesn't work well in 3 years.

If need be, I can cite presentations from professionals. I'm not just pulling this stuff from my ass.
Coordinator
Feb 5, 2008 at 5:33 PM
I've given you examples of immediate messages I use everyday. The problem is you guys against them because of system dependancies.

Class Foo;
Class FooBar;

Foo needs the tiniest amount of information from FooBar, but on the occasion is does need the information, it needs it the same frame.

By your logic, even if Foo only speaks with FooBar 1 frame per minute, they are dependencies on each other, so the developer now has to find a way to connect the two systems together so that know about each other so they may call functions from one another.

Ok, its as simple as this:

  • No immediate messaging means anytime we send information that we need immediately, we need to use a function, and therefore need to directly connect objects together, causing dependancies.

  • Immediate messaging means we can send information to a specific interface, and it would fill the message with info. This means we do not cause dependancies.

If we refer to our previous example, but expanded:

Foo and FooBar are part of different main interfaces. Foo sends the message to FooBar's interface, which fills the message with the info from FooBar because it is connected to FooBar. DONE! This means I don't have to connect two classes from different interfaces, and keeps the interfaces independant and easily separated. It would be a shame to connect two classes directly just to pass a small amount of info.

I really don't know how many ways I can explain it. If I weren't under NDA I'd be giving you guys concrete examples, but unfortunately that cannot happen.
Coordinator
Feb 5, 2008 at 5:45 PM
Shaw, I believe I understand exactly what you're saying. But I'm not sure it is a huge issue.

Immediate messages are just like a function:
Call function, do task and/or possibly recieve feedback information.
Send message, do task and/or possibly recieve feedback information.

I'm not implying any delay in the message whatsoever, the engine would literally pause while this message did its work. This part does imply some overhead, and that is why I believe messages of this type would be used in non-performance situations, such as things that only occur a couple of times per frame at most. Anything that needed performance should probably be coupled directly anyhow.

A message is just a consistant format. An easy way to say, perform this action, with this interface. If every interface had a simple way of exposing anything we wanted, then I could just do this with functions, like

Foo->GetFooBarsInterface()->FooBar()->AnyPublicFunction();

In fact, this way works fine if we want to skip messaging. The ony issue is that Foo needs to have an instance of FooBar's Interface. This would imply that Interfaces were singletons.

I was just picturing that Foo sends a message to FooBar's interface, message inside of that interface would perform the same function as AnyPublicFunction. This doesn't require that Foo have an instance of FooBar's interface, it simply sends the message to the message handler, and that handler has access to every interface, and simply directs it to the FooBar interface.
Feb 5, 2008 at 6:06 PM

LordIkon wrote:

I'm not implying any delay in the message whatsoever, the engine would literally pause while this message did its work.


And this is exactly what I'm trying to avoid. These "bubbles" or "hiccups" in task processing can bring the engine to its knees and completely negate concurrency. You may guarantee that it'll only happen a few times a second. But over time you find more uses for it and start using it as a hack even. Suddenly you're doing it a hundred times a frame and introducing all sorts of stalls that are worse than just using locks in the first place.


This part does imply some overhead, and that is why I believe messages of this type would be used in non-performance situations, such as things that only occur a couple of times per frame at most. Anything that needed performance should probably be coupled directly anyhow.


I only ever intended direct coupling to work between SceneManager and Physics which are really one in the same and share state.


A message is just a consistant format. An easy way to say, perform this action, with this interface. If every interface had a simple way of exposing anything we wanted, then I could just do this with functions, like

Foo->GetFooBarsInterface()->FooBar()->AnyPublicFunction();

In fact, this way works fine if we want to skip messaging. The ony issue is that Foo needs to have an instance of FooBar's Interface. This would imply that Interfaces were singletons.


This sort of dependency (and singletons, too!) is what I'm trying to avoid, as well.


Immediate messages are just like a function:
Call function, do task and/or possibly recieve feedback information.
Send message, do task and/or possibly recieve feedback information.


Let me propose an alternative, which zero loss in functionality. As I mentioned above, tasks broadcast their internal state when they complete their processing for a frame. Your task (the one you envision sending these immediate messages) will receive these state updates. The key here is the following: your task will decide if it cares about this state information, and cache it. When it comes time for your task to execute, it decides that it needs some information from another task. Instead of sending a message to that task, it queries its local cache for the last known state of the desired task. No messages, no interface calls, no pauses, no locks, just a local data look-up. Each task will only cache the state changes it cares about, and it will store them however is most efficient for the usage pattern.
Coordinator
Feb 5, 2008 at 6:12 PM


shawmishrak wrote:

And this is exactly what I'm trying to avoid. These "bubbles" or "hiccups" in task processing can bring the engine to its knees and completely negate concurrency. You may guarantee that it'll only happen a few times a second. But over time you find more uses for it and start using it as a hack even. Suddenly you're doing it a hundred times a frame and introducing all sorts of stalls that are worse than just using locks in the first place.


This is no different than a function, except the performance difference. I can assure you, when done right the performance difference is negligable.
Coordinator
Feb 5, 2008 at 6:29 PM
What are the downsides to caching information? What if it is information I will only need one frame per minute or less?
Feb 5, 2008 at 6:54 PM

LordIkon wrote:

This is no different than a function, except the performance difference. I can assure you, when done right the performance difference is negligable.


The problem is in what the function does. In this case, the function needs to query another system for state information. You and the target may be on different threads, so you need to synchronize access to the state data. Either the target caches its state to quicken the data retrieval, or you force either yourself or the target to block on a lock while you copy the state data, therefore reducing both you and the target of the function call to sequential execution.

This has nothing to do with the speed of function calls or message passing. It has everything to do with maintain consistent state across threads which both need access to the state data.


What are the downsides to caching information? What if it is information I will only need one frame per minute or less?


The downsides to caching are the memory requirements of passing state information around and storing it. Obviously you only want to receive and store state information that you actually care about. If you know you only need the state information every minute, then chances are your task is only running once per minute. You just keep collecting state changes you are interested in, overwriting previous state data.
Coordinator
Feb 5, 2008 at 7:07 PM
Is this asyncronous engine going to be user friendly? It is already sounding like I won't know what I get when I request information from other systems. Caching doesn't sound like an easy solution either. The devs need to know this almost as well as we do, or they don't know how to leverage the power of it.
Feb 5, 2008 at 7:57 PM
Edited Feb 5, 2008 at 7:57 PM
I have to say Shaw, I'm impressed about your knowledge, nice to see such a dedication to HW architecture find it's way to an indie project.

I only have two comments


LordIkon wrote:
Is this asyncronous engine going to be user friendly?


No it's not, at least not for game developers. Async and threaded programming is something not many actually understands and certainly a game developer who is used to AngleScript/UnrealScript/DarkBasic etc isn't going to understand anything going on in the engine. But then again they aren't supposed to be coding at that level.


LordIkon wrote:
I really don't know how many ways I can explain it. If I weren't under NDA I'd be giving you guys concrete examples, but unfortunately that cannot happen.


This makes me really nervous, as you are indirectly implying that you could be writing code that falls under your NDA, it might even be worse as any code we write, which is similar to anything you do on your job would also violate NDA. Further many NDA's prohibit the envolvement into projects within the same type of field, unless a Cross Signed NDA has been signed by all involved.

So just to make sure can you please state that this is not the case, and any code produced under the lifetime of the project will and does not in any way violate your current NDA.
Coordinator
Feb 5, 2008 at 10:44 PM
Edited Feb 5, 2008 at 10:48 PM
I was working on the engine before my NDA, and signed an agreement with them about that, my only requirement is that no prioprietary knowledge or technology from work is in my code. So anything I learn at work that isn't known in the industry (like a new type of physics or something) couldn't be used in the engine.

No worries, I wouldn't want to jeopardize the project, or my job. Everything of mine in the engine is stuff I learned on my own or is common/non-proprietary knowledge, that is all they care about.
Feb 5, 2008 at 11:27 PM
Of course, implementing such a beast is another story. Our current messaging system is a step in the right direction, but it would probably need some modifications. This is definitely the direction I want to go, though. The hard part would be thinking in terms of atomic tasks and efficient task scheduling. If I get some time, I may work on a proof of concept mock-up.

By necessity, the game-layer would be event driven and look sequential. Though under the hood the script system would break script events down into atomic tasks. So yes, the engine layer would be fairly difficult to understand for someone who has no experience with threading and concurrent programming. The game code would be elegant and not expose the details, though.
Coordinator
Feb 5, 2008 at 11:51 PM
For now I'll see what we come up with, it isn't worth arguing this into the ground. I trust that if we come upon the need for immediate messages you guys will see that and I won't need to argue it anyway.