Page 1 of 1

Network Game Skeleton - free, well-commented source code!

PostPosted: Tue Mar 27, 2007 3:17 pm
by Karl G.
Download the Source (6 MB)
View the Documentation

I dug up some old source code that I had created almost a year ago now, and tweaked it a bit so all of you who want to have a look at a real, working networked 3d application can do so. This project contains:
  • Fully-functional client
  • Fully-functional server (yes, it works over the internet)
  • Support for up to 16 players simultaneously (although this is only limited by a #define statement)
  • OPTIMIZED, ANIMATED .X MESHES!
  • DirectInput keyboard and mouse recognition
  • Camera control
  • Only ~3500 lines of code
  • Simple, funtion-oriented design
  • Complete online documentation (also included in download)
  • Precompiled demos in the /Bin/ directory


Now, for the disclaimer. This source doesn't have any kind of chat capability, items, weapons, terrain (other than a flat sheet of grass), etc. Essentially, it has no content--but the core of the application is there for you to tinker with, and add on to.

Also, you might find that the server code isn't too well documented. Most of the documentation for this code can be found in the source files itself--I have yet to go through and add comments to all of the function declarations in the headers.

Enjoy! I'd love to hear from anyone who finds this useful :D

Karl

PostPosted: Tue Mar 27, 2007 5:08 pm
by figgles
ack.

This sample isn't working for me. It keeps triggering a breakpoint in ntdll.dll (native API DLL).

I ran it through the debugger:

ntdll.dll!7c901230()
d3d9d.dll!_MemState() + 0xaf bytes
d3d9d.dll!_MemFini() + 0x31 bytes
d3d9d.dll!_DllMain@12() + 0x42d bytes
d3d9d.dll!__DllMainCRTStartup@12() + 0x52 bytes

Just by look at the DLL backtraces, I can tell you right now that your code is leaking memory. I have seen that backtrace a thousand times. I am not sure whether Direct3D 9's memory leak checker checks only its allocations or the entire CRT heap, but whatever it is, there is some kind of memory leak, and it isn't liking it.

Right now, the client connects to the server them immediately exits, where releasing the Direct3D9 object causes the breakpoint to be triggered.

Leaking Direct3D9 objects can happen for a number of reasons, such as not using Device->SetTexture(i, NULL) for all passes. SetTexture() with a valid pointer calls AddRef() so calling Release() on the object itself will NOT release the texture. That was a fun one for me to track down.

I believe the source of the memory leak is in AnimatedMesh::LoadMeshFromX():
(m_pd3dDevice = pDevice)->AddRef();

..because the line:
hr = m_pAllocateHierarchy->LoadMeshHierarchyFromX(pDevice, strFileName, (D3DXFRAME**)&m_pFrameRoot, &m_pAnimationController);

fails, which calls BasicAllocateHierarchy::LoadMeshHierarchyFromX() and finally this line is executed:
D3DXLoadMeshHierarchyFromX( strFileName, 0, pDevice, this, NULL, ppFrameHierarchy, ppAnimController );

which returns E_FAIL.

This might be due to an API change in D3DX. I had to rewrite all of my animation code because the X parser interface was removed. So I said fck it and wrote my own crossplatform/API independent X parser/animation library. Much better like that, so so much better.


A few other messages I got that you should pay attention to:

Direct3D9: (WARN) :Indexbuffer created with POOL_DEFAULT but WRITEONLY not set. Performance penalty could be severe.
Direct3D9: (WARN) :Vertexbuffer created with POOL_DEFAULT but WRITEONLY not set. Performance penalty could be severe.
Direct3D9: (WARN) :Indexbuffer created with POOL_DEFAULT but WRITEONLY not set. Performance penalty could be severe.
Direct3D9: (WARN) :Vertexbuffer created with POOL_DEFAULT but WRITEONLY not set. Performance penalty could be severe.

D3DPOOL_DEFAULT is volatile (i.e. pure video memory, not backed by system memory), so if you create them and someone Alt+Tab's, and you have no code to handle this, there will be problems. Reading from non-CPU accessable video memory is likely to be slow anyways, and for most purposes (such as animating a character) this memory pool should be write only. For static things such as the terrain, you might consider MANGED pool.


Direct3D9: (INFO) :MemFini!
Direct3D9: (WARN) :Memory still allocated! Alloc count = 91

There is the official count. You have 91 unfreed allocations. You might want to fix that too =\


Overall, I can't say much about the program since all I have had are problems. Hopefully that information will help you. The code itself seems really hacked together and slightly unprofessional -- I know you can do better.

PostPosted: Tue Mar 27, 2007 7:21 pm
by Karl G.
The POOL_DEFAULT/writeonly warning comes from the internals of the animation code, and doesn't mean anything because those are just temporary buffers anyway. I'm not sure why D3DXMesh decides to make them this way, because I don't control those buffers.

There is code to handle loss of the device, although much of it is simply managed code. I'm not sure why D3DXLoadMeshHierarchyFromX would fail--have you checked the file name provided to it? It should be "tiny/Tiny_skin.dds" Even when the function fails, I don't get the errors you mentioned.

Yes, this is old code. Have you recompiled the code on your machine?

PostPosted: Tue Mar 27, 2007 8:58 pm
by figgles
Yes, I verified the filename (and all other parameters to the function) while I was running it through the debugger, though it wasn't (and probably shouldn't) be a dds file (sp on your part?), it was some X file in the tiny/ directory. If the filename was wrong, it wouldn't be because I changed it. I did recompile the code, as I couldn't have debugged the executable without the *.pdb files in VC 2005.

You aren't getting many errors (especially the memory leak ones which you really should pay attention to) because you probably have the D3D error messages turned down/off. You need to install the D3D9 developer debug runtime in order to get them, and drag the slider to increase the verbosity. If you have checked "Break on D3D Error" and "Break on memory leak" too, you will probably catch a lot more errors in your code and get a few grey hairs while you are at it. ;)

...from the internals of the animation code...

...because I don't control those buffers.


*sigh*
/rant
The fact that you have that little control over your code is especially painful. D3DX's functions are good when you are first starting to learn D3D9, but some time you really need write your own code. You'll learn a lot more about the subject if you have to go from theory to implementation to realtime implementation. Any D3D9 code I write nowadays is in C, so D3DX isn't even an option. For this sample framework, I suppose it is appropriate, but then again, you would think that anyone examining a multiplayer 3D game framework would be not so much of a beginner.

The problem with D3DX's animation code is that its braindead and needlessly complicated interfaces almost force you to only use D3DXLoadMeshHeirarchyFromX() since to do so otherwise and try to make a different file format work with it would be absolutely hurtful. I wouldn't be surprised if the reason you are having so hard a time getting animations to work with a different file format is because you rely (arguably too much) on D3DX to do the real work for you.

Perhaps I have a not-invented-here syndrome, but then again, I haven't regreted writing my own animation/X parser code after I ran some of my programs on operating systems/processors I didn't even know existed at the time I wrote it.
/end rant

PostPosted: Wed Mar 28, 2007 6:27 am
by Karl G.
Yes, the file should be tiny_4anim.x. I was looking at the texture file.

Keep in mind that this is free. I just decided to share some old code with people who might appreciate it. If you don't, that's fine--just leave it alone.

PostPosted: Sat Mar 31, 2007 8:56 pm
by Neorift
That's actually a pretty cool example.