Jump to content
  • Advertisement
  • entries
  • comments
  • views

GameDev Books



Updated 3/27/2019

I study how to write my own game engines using modern OpenGL/C# and WebGL/TypeScript. I advice you this book: C# Game Programming: For Serious Game Creation. This book shows how to write your own game engine with maintainable code using TDD. This is a great book. It is not for GameDev only. It shows how to develop big projects in general. I know that you like to write games using Game Engines like Unity. By this book you will know basics of Linear Algebra, Shader Math, Game Physics and so on. Shader Math is important for Unity too because you need to write shaders for Unity. HLSL and GLSL are very similar. It is a great book really.

Behaviour-Driven Development:

Test-Driven Development:

Writing Games:

Computer graphics:

Math and Physics:



Recommended Comments

Thanks for these. I also have Multiplayer Game Programming and think it's a good game development book. It covers a lot in little space, including Peer-to-Peer and Client-Server architecture, reliable UDP, client-side prediction and interpolation, and Steam integration. Also, it's a decent introduction to networking in general.

Share this comment

Link to comment

@Davindius thank you for your comment. I am going to rewrite the RoboCat game from the book to C#. This book is very important for me because it shows how to use low level API (Winsock, WSA, Windows Socket API). I study System.Net.Sockets. The best way to study something is writing simple clone games. I will write prototype games with local network like: Pong, Snake, Battle City and so on. I will improve these games for practice, for getting skills. Programming is a practice on 80% and 20% - theoretical knowledges. I think so. Sorry for my English.

Share this comment

Link to comment

Hi there,

As someone who wants to explore the world of Gamedev without getting hands on with game engines this really is a good list. I do have one question though: do you have any recommendations for books approaching this similar topic but using C++ ?

This might be a silly thought (I'm very new to all this, even programming) but what really is the long term difference in obtaining this knowledge with C# rather than C++?

Share this comment

Link to comment

I study three languages: C#, TypeScript and Python.

My goals:

  • C# - OpenGL 3.1, WinForms, WPF, Unity
  • TypeScript - WebGL 1.0, Three.js, Babylon.js, Phaser, Pixi.js
  • Python - plugins for Blender and Gimp

C# and OpenGL allows to write hybrid (graphics + GUI using WinForms and WPF) non game applications. WebGL and TypeScript allow it online but browser has restrictions. I like to study math (linear algebra, geometry and physic). And I like to study how to make simple game engines for simple games with multiplayer using Node.js, TypeScript, Socket.io, WebSockets with free hosting on Heroku where I can use multiplayer and databases (MongoDB and ClearDB/MySQL). I like to write shaders using math. I study all these stuffs together.

Share this comment

Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Advertisement
  • Advertisement
  • Blog Entries

  • Similar Content

    • By Catch_0x16
      Hello Folks,
      I'm writing a plugin for a simulator called 'X-Plane 11'. My plugin essentially calls on a DLL (Which I've written) that makes OpenGL calls to draw graphics onto the active draw target (it does no OpenGL initialization). I want this external DLL to represent the logic behind a computer screen, but not be directly coupled with the OpenGL context that it is being drawn to. In this current instance for example, I am drawing it to the screen in X-Plane, however, I may at some point want to draw it to the screen of a different game engine, or perhaps even just a windows program.
      The way I am trying to achieve this:
      Generate a frame buffer and texture Initialize texture and add it to the framebuffer On the drawcall... Bind to the frame buffer Call the dll's draw method Un-bind the frame buffer Bind to the host applications framebuffer Bind to the associated texture Draw a quad in the corner of the screen with appropriate texture coordinates Un-bind the texture I have the problem though that the output is always just a black square...(See attached image)
      The code goes a little like this (Only showing the relevant bits):

      #include <Windows.h> #include <string> #include "PluginHeader.h" #include <GL\glew.h> #include <gl\GL.h> #include <gl\GLU.h> #include "MFDSim.h" HINSTANCE g_MfdSimLibHandle = 0; XPLMWindowID g_MfdWindowID = 0; GLuint g_FrameBufferID = 0; GLuint g_fbTex = 0; GLuint g_rbo = 0; unsigned int g_MfdScreenWidth = 0; unsigned int g_MfdScreenHeight = 0; ///////////////////////////////////////////////////// // Standard plugin functions ------------------------ PLUGIN_API int XPluginStart( char* outName, char* outSig, char* outDesc) { strcpy(outName,"MFD Sim"); strcpy(outSig, "mfd"); strcpy(outDesc, "); int retVal = TRUE; glewInit(); HINSTANCE g_MfdSimLibHandle = LoadLibrary("./Resources/plugins/MFD_Sim_Plugin/win_x64/MFDSim.dll"); if (g_MfdSimLibHandle != nullptr) { try { MFD::mfdInit("./Resources/plugins/MFD_Sim_Plugin/config/layout.xml"); MFD::mfdGetWidthHeight(g_MfdScreenWidth, g_MfdScreenHeight); } catch (const std::exception& ex) { retVal = FALSE; } } else { retVal = FALSE; } return retVal; } PLUGIN_API void XPluginStop() { FreeLibrary(g_MfdSimLibHandle); } PLUGIN_API int XPluginEnable() { // We need to revert back to the appropriate frame buffer after we're done GLint currentReadFB = 0; GLint currentDrawFB = 0; glGetIntegerv(GL_READ_FRAMEBUFFER, &currentReadFB); glGetIntegerv(GL_DRAW_FRAMEBUFFER, &currentDrawFB); XPLMRegisterDrawCallback(OnDrawCall, xplm_Phase_LastCockpit, TRUE, nullptr); // Generate OPENGL stuff we need glGenFramebuffers(1, &g_FrameBufferID); glBindFramebuffer(GL_FRAMEBUFFER, g_FrameBufferID); glGenTextures(1, &g_fbTex); glBindTexture(GL_TEXTURE_2D, g_fbTex); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, g_MfdScreenWidth, g_MfdScreenHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glBindTexture(GL_TEXTURE_2D, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, g_fbTex, 0); glGenRenderbuffers(1, &g_rbo); glBindRenderbuffer(GL_RENDERBUFFER, g_rbo); glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, g_MfdScreenWidth, g_MfdScreenHeight); glBindRenderbuffer(GL_RENDERBUFFER, 0); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, g_rbo); glBindFramebuffer(GL_READ_FRAMEBUFFER, currentReadFB); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, currentDrawFB); return TRUE; } PLUGIN_API void XPluginDisable() { XPLMUnregisterDrawCallback(OnDrawCall, xplm_Phase_LastCockpit, TRUE, nullptr); glDeleteFramebuffers(1, &g_FrameBufferID); glDeleteTextures(1, &g_fbTex); } PLUGIN_API void XPluginReceiveMessage( XPLMPluginID inFrom, int inMsg, void* inParam) { } // Boilerplate DLL stuff BOOL WINAPI DLLMain( _In_ HINSTANCE hInstance, _In_ DWORD fdwReason, _In_ LPVOID lpvReserved) { return TRUE; } ///////////////////////////////////////////////////// // MFD functions ----------------------------------- void HandleWindowKeyEvent(XPLMWindowID inWindowID, char inKey, XPLMKeyFlags inFlags, char inVirtualKey, void * inRefcon, int losingFocus) { if (inWindowID == g_MfdWindowID) { } } int OnDrawCall(XPLMDrawingPhase inPhase, int inIsBefore, void * refCon) { // We need to revert back to the appropriate frame buffer after we're done GLint currentReadFB = 0; GLint currentDrawFB = 0; glGetIntegerv(GL_READ_FRAMEBUFFER, &currentReadFB); glGetIntegerv(GL_DRAW_FRAMEBUFFER, &currentDrawFB); // Bind to our own frame buffer and draw our MFD glBindFramebuffer(GL_DRAW_FRAMEBUFFER, g_FrameBufferID); glBindFramebuffer(GL_READ_FRAMEBUFFER, g_FrameBufferID); glBindTexture(GL_TEXTURE_2D, g_fbTex); glClear(GL_COLOR_BUFFER_BIT); glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glEnable(GL_TEXTURE_2D); if (!MFD::mfdDraw(1.0f)) { // TODO: Handle failure to draw } glBegin(GL_LINES); glColor4f(1.0f, 0.1f, 0.1f, 1.0f); glVertex2f(0.0f, 0.0f); glVertex2f(100.0f, 100.0f); glEnd(); glBindFramebuffer(GL_READ_FRAMEBUFFER, currentReadFB); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, currentDrawFB); glEnable(GL_TEXTURE_2D); glBegin(GL_QUADS); glVertex2f(0, 0); glTexCoord2f(0.0f, 0.0f); glVertex2f(0, g_MfdScreenHeight); glTexCoord2f(0.0f, 1.0f); glVertex2f(g_MfdScreenWidth, g_MfdScreenHeight); glTexCoord2f(1.0f, 1.0f); glVertex2f(g_MfdScreenWidth, 0); glTexCoord2f(1.0f, 0.0f); glEnd(); glBindTexture(GL_TEXTURE_2D, 0); return 0; }  

    • By vvoodenboy
      My name is... nobodycaresbecauseitsnotimportant.
      I'm working on my own card game. I'm just in a stage of connecting some 'dots' of game's mechanics.
      I'm looking for a concept / 2D artist - because its time to give it some shape - I've a concept of a dark fantasy world where I want to place the plot but there is a lot of space for creativity.
      If you are interested please shout here or on discord (vvoodenboy#3207) or vvoodenboy@gmail.com.
      Have a nice day!
    • By Cubic321
      Hello everybody!

      Now I'm developing a game with a simple unobtrusive gameplay. The goal of the game is to get to the other side by jumping on platforms. Control is a single jump button, but it's not that simple. In this case, I like Nintendo's approach to its games. Where, at first glance, the simple control of the character hides a deep mechanics that the player discovers gradually.
      I want to implement this approach in my game. For example, if the landing immediately press jump, the character will make a combined jump with a flip. For combined jump player will earn more game points. 
      Game points can be spent, for example, that would save the game on a special platform for this. Thus, it is profitable for the player to plan his actions. In addition, for example, if the player lands on the edge of the platform, he will lose his balance and fall, but if the landing immediately press the jump button, the player will not fall and will continue to jump.
      The game world too is not simple. Platforms have their own character: there are disappearing platforms,those that randomly move, move apart, etc. But more about that later.
      Now ready character design, platform design and entry-level background. As well as basic animation and mechanics.
    • By Range
      Good day. I am find for information on how to create texture arrays in d3d12. In d3d11, I calmly figured out how to create a texture array from several textures:
      I upload several dds - textures of the same resolution in the engine I create ID3D11Texture2D* and map date into it all loaded textures in shader I use texture2darray in pixel shader: Texture2DArray textures : register(t0); Now I am looking for something like that for d3d12. For load the textures, I use DDSTextureLoader.h/.cpp from microsoft. So I'm loading a few textures. How can I create a texture array from them and pass it to a pixel shader? I will be glad to some example. Thank.
      PS: I searched the forum, but I didn’t find anything.
    • By dexam234
      hey guys,
      i have a problem over here with vertex shaders and going to need some professional help, so i thought i create a thread here.
      i just decided to work this feature out for me, 2 days ago. so please dont expect me to have any experience in programming D3D.
      i am trying to work this out on my own as good as i can, but i would really appreciate if someone could help me a bit or give me a push in the right direction.
      i am paying for the solution, so you won't waste your time, if you decide to join me on this case.
      but ok, lets start:
      first of all, you have to know that i am editing a very old game, which is using Direct X 8. the water in this game is basically a simple plane, which is using a normal texture projected onto it.
      so basically its just a plane with a texuture, that is initializing a alpha state for the texture, so you can look through the water ingame.
      no shadows, no reflections, no animations yet. my first goal is to get the inverseViewMatrix working, to make at least the shadows of the world appear in the water.
      so, here's the code of the actual render state of the water:
      So, i noticed there's already something started for inversing the view ('&InverseTheView').
      in another function, for setting the Inverse View and Shadow Matrices, its declared:
      InverseTheView = pCamera->GetInverseViewMatrix(); D3DXVECTOR3 v3Target = pCamera->GetTarget(); D3DXVECTOR3 v3LightEye(v3Target.x - 1.732f * 1250.0f, v3Target.y - 1250.0f, v3Target.z + 2.0f * 1.732f * 1250.0f); D3DXMatrixLookAtRH(&m_matLightView, &v3LightEye, &v3Target, &D3DXVECTOR3(0.0f, 0.0f, 1.0f)); DynamicShadow = InverseTheView * LightView * DynamicShadowScale;  
      okay, so far so good. i tried to add the Inversed View to my Water rendering state:
      void LoadWaterMaterial() { char buf[256]; for (int i = 0; i < 30; ++i) { sprintf(buf, "C:/test/water/%water_1d.dds", i+1); WaterInstances[i].SetImagePointer((CGraphicImage *) CResourceManager::Instance().GetResourcePointer(buf)); } } void RenderWater() { // Saving Render State D3DXMATRIX oldView = LightView; // Old light view D3DXMATRIX oldLight; // old light D3DXPLANE plane(0.0f, 1.0f, 0.0f, 0.0f); D3DXMATRIX invertMatrix; D3DXMatrixReflect(&invertMatrix, &plane); oldView = ms_matWorldView; D3DXMATRIX vue = oldView; D3DXMatrixMultiply(&vue, &vue, &invertMatrix); // Inverse view D3DXMatrixMultiply(&LightView, &LightView, &invertMatrix); // Inverse light STATEMANAGER.SaveRenderState(D3DRS_ZWRITEENABLE, FALSE); STATEMANAGER.SaveRenderState(D3DRS_ALPHABLENDENABLE, TRUE); STATEMANAGER.SaveRenderState(D3DRS_STENCILENABLE, true); STATEMANAGER.SaveRenderState(D3DRS_STENCILFUNC, D3DCMP_ALWAYS); STATEMANAGER.SaveRenderState(D3DRS_STENCILREF, 0x1); STATEMANAGER.SaveRenderState(D3DRS_STENCILMASK, 0xffffffff); STATEMANAGER.SaveRenderState(D3DRS_STENCILWRITEMASK, 0xffffffff); STATEMANAGER.SaveRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP); STATEMANAGER.SaveRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP); STATEMANAGER.SaveRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE); STATEMANAGER.SaveRenderState(D3DRS_CULLMODE, D3DCULL_NONE); STATEMANAGER.SaveRenderState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_COLOR1); STATEMANAGER.SaveRenderState(D3DRS_COLORVERTEX, TRUE); STATEMANAGER.SaveRenderState(D3DRS_SPECULARENABLE, TRUE); STATEMANAGER.SaveRenderState(D3DRS_SPECULARMATERIALSOURCE, D3DMCS_COLOR2); /// Reflection D3DXMATRIX reflection = vue; D3DXMatrixScaling(&reflection, m_fWaterTexCoordBase, -m_fWaterTexCoordBase, 0.0f); STATEMANAGER.SaveTransform(D3DTS_TEXTURE0, &reflection); LPDIRECT3DTEXTURE9 textureEau = m_WaterInstances[((ELTimer_GetMSec() / 30) % 250)].GetTexturePointer()->GetD3DTexture(); STATEMANAGER.SetFVF(D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX0 | D3DFVF_TEX1); STATEMANAGER.SetTexture(0, textureEau); STATEMANAGER.SaveTextureStageState(0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR); STATEMANAGER.SaveTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_PROJECTED); STATEMANAGER.SaveSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); STATEMANAGER.SaveSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); STATEMANAGER.SaveSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR); STATEMANAGER.SaveSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_MIRROR); STATEMANAGER.SaveSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP); STATEMANAGER.SaveSamplerState(0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP); STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE); STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); // Start of Water STATEMANAGER.SetTexture(0, WaterInstances[((ELTimer_GetMSec() / 70) % 30)].GetTexturePointer()->GetD3DTexture()); D3DXMatrixScaling(&TransformTextureToWater, WaterTextureCoordBase, -WaterTextureCoordBase, 0.0f); D3DXMatrixMultiply(&TransformTextureToWater, &InverseTheView, &TransformTextureToWater); STATEMANAGER.SaveTransform(D3DTS_TEXTURE0, &TransformTextureToWater); STATEMANAGER.SaveVertexShader(D3DFVF_XYZ|D3DFVF_DIFFUSE); STATEMANAGER.SaveTextureStageState(0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION); STATEMANAGER.SaveTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2); STATEMANAGER.SaveTextureStageState(0, D3DTSS_MINFILTER, D3DTEXF_LINEAR); STATEMANAGER.SaveTextureStageState(0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR); STATEMANAGER.SaveTextureStageState(0, D3DTSS_MIPFILTER, D3DTEXF_LINEAR); STATEMANAGER.SaveTextureStageState(0, D3DTSS_ADDRESSU, D3DTADDRESS_WRAP); STATEMANAGER.SaveTextureStageState(0, D3DTSS_ADDRESSV, D3DTADDRESS_WRAP); STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE); STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); STATEMANAGER.SetTexture(1,NULL); STATEMANAGER.SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); STATEMANAGER.SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); // Restoring Render State STATEMANAGER.RestoreVertexShader(); STATEMANAGER.RestoreTransform(D3DTS_TEXTURE0); STATEMANAGER.RestoreTextureStageState(0, D3DTSS_MINFILTER); STATEMANAGER.RestoreTextureStageState(0, D3DTSS_MAGFILTER); STATEMANAGER.RestoreTextureStageState(0, D3DTSS_MIPFILTER); STATEMANAGER.RestoreTextureStageState(0, D3DTSS_ADDRESSU); STATEMANAGER.RestoreTextureStageState(0, D3DTSS_ADDRESSV); STATEMANAGER.RestoreTextureStageState(0, D3DTSS_TEXCOORDINDEX); STATEMANAGER.RestoreTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS); STATEMANAGER.RestoreRenderState(D3DRS_DIFFUSEMATERIALSOURCE); STATEMANAGER.RestoreRenderState(D3DRS_COLORVERTEX); STATEMANAGER.RestoreRenderState(D3DRS_ZWRITEENABLE); STATEMANAGER.RestoreRenderState(D3DRS_ALPHABLENDENABLE); STATEMANAGER.RestoreRenderState(D3DRS_CULLMODE); } The Output is, i would say strange. its flickering, framing between black and gray color. but its not inversing the view.
      Does it have something to do, with clipping the frustum view?
      I really do not have any clue how to work with this properly. i would really appreciate if someone here gives me the push in the right direction, as mentioned.
      you'll get rewarded, too!
      thanks for reading and best regards
  • 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!