Engine Structure and C vs C++

Discussion in 'Game Development and Modding' started by root, Jul 31, 2018.

  1. Jul 31, 2018
    root
    Veteran Member
    "Wacka-Wacka-Wacka-Wacka-Wacka-Wacka-Wacka-Wacka-BLEIUP"
    Join Date: Aug 21, 2012
    Location: At a computer
    Posts: 309
    Age: 17
    Me and Yacker have been working on a game engine for atleast personal use in C, and I'm wondering if anyone here who has experience might have feedback/ideas/better ways to do stuff about the overall engine structure so far.

    One of the main points of the engine is to make it (relatively to my previous attempts) easy to swap out the renderer/input systems (as well as seperate the game specific stuff itself from most of the base engine), and so far it works like this:

    Renderer/input files are in their own folder, which is switched in the Makefile. Example:
    RENDERER_SDL = TRUE

    GAMEOBJCODE = game/objects/player.c

    ifdef RENDERER_SDL
    #OBJS specifies which files to compile as part of the project
    OBJS = main.c math2.c sdl/render.c sdl/input.c sprite.c image.c object.c game/gameobjects.c $(GAMEOBJCODE)

    #INCLUDE_PATHS specifies the additional include paths we'll need
    INCLUDE_PATHS = (SDL2 include path here) -I$(CURDIR)\sdl -I$(CURDIR)\game -I$(CURDIR)\game\objects

    #LIBRARY_PATHS specifies the additional library paths we'll need
    LIBRARY_PATHS = (lib path here)

    #LINKER_FLAGS specifies the libraries we're linking against
    LINKER_FLAGS = -lmingw32 -lSDL2main -lSDL2 -lSDL2_image
    endif

    The textures are abstracted into an Engine_Texture struct that contains a pointer to the actual texture, and the width/height. So theoretically it shouldn't matter if its using SDL or something else.. of course I haven't tried to replace the renderer so for all I know it could fall apart.

    Input would be abstracted into a game specific bitwise variable with enough bits for every button needed, that's actually checked by the game logic.

    Sprites are a string indexed array where an object would just call Sprite_Get("SPR_EXAMPLE"), then get back an ID for it in the array. If it doesn't have that sprite it loads its framerects/texture name from that sprites file.. and then it uses basically the same system for the textures themselves.
    Yacker programmed this, but I'm still not 100% sure if its a good idea in terms of performance..

    Sound would probably use the same idea, but we haven't started on that yet.

    Objects use an array of structs with function pointers to Create, Step, and Draw functions for each object type in order. (Each object has a struct type, though all of them start with the same variables) And theres a function to add an object to this array by passing it the function pointers.

    The actual object list is a void** array of pointers to the objects (If they exist. When objects are deleted they move every pointer past it in the array 1 back, and it only loops through how many objects have been allocated rather than every index in the array)

    There's also the matter of it being C. Yacker told me C++ can have constructor/deconstructor functions (basically what we're doing for objects already but built into the language) and object struct types (Which would become classes) can be in an array so each object wouldn't need its own variant of "objects[id] = calloc(1,sizeof(obj_type_here_t));". Would it be a good idea to switch over?

    Thanks in advance if anyone has any thoughts on this.
     
    Last edited: Jul 31, 2018
  2. Aug 4, 2018
    Clownacy
    Senior Member
    "Wahoo! Upgrade!"
    Join Date: Jan 13, 2016
    Location:
    Posts: 54
    Honestly, I find myself writing code that could be a bit simpler in C++ thanks to its object-oriented design, but I've never made the switch to it. I guess it's partly down to assembly being my first language, so I'm perfectly comfortable with plain old code and data, and not having objects and fancy casts muddy the water.

    I think it would be best to change how you handle objects. You mention shuffling almost every object pointer in the array when one is deleted, but using a linked list instead would avoid this entirely. To give a quick comparison, linked lists excel in insertion/deletion of entries, but don't do so well for access via index, which you probably won't need to do anyway.

    Personally, I wouldn't use strings for identifying sprites/sounds. I think one of my first OpenGL test programs did that, but eventually I started using enums instead. An int is just faster than a string.

    Your method of swapping out rendering/input backends seems fine. I don't really have anything to add to it. That project of mine I linked to earlier does something similar with its various decoder backends.
     
  3. Aug 5, 2018
    root
    Veteran Member
    "Wacka-Wacka-Wacka-Wacka-Wacka-Wacka-Wacka-Wacka-BLEIUP"
    Join Date: Aug 21, 2012
    Location: At a computer
    Posts: 309
    Age: 17
    1.Well, in programming games, I often do stuff like (GML):
    var tempbullet=instance_create(x,y,objBullet);
    tempbullet.xspeed=leftright*8;
    which would be easier with an array index. I should probably add a variable to objects of which spawned it though.

    2.It doesn't check the string every frame, only when it changes sprite. (Not sure if you misunderstood that part just to be sure)
    Yacker wanted this to make modding easier. (And to be fair I think its easier to use than an enum)
     
  4. Aug 6, 2018
    Clownacy
    Senior Member
    "Wahoo! Upgrade!"
    Join Date: Jan 13, 2016
    Location:
    Posts: 54
    I'm not sure what that code has to do with array indexes...?

    I know the strings are only used when a sprite changes. I'm not saying it will lag the game, just that it's unneccesary overhead, and not best practice. Unless you're generating those strings with sprintf or something, the only thing that makes an enum harder to use than a string is that you have to define enums before you can use them. And also the need to namespace them, I guess.
     
    Last edited: Aug 6, 2018