Advertisement Jump to content
  • Advertisement

Strewya

Member
  • Content Count

    204
  • Joined

  • Last visited

Community Reputation

2802 Excellent

About Strewya

  • Rank
    Member

Personal Information

  • Role
    Programmer
  • Interests
    Design
    Programming

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. I'm not making an engine nor a game, more like experimenting with stuff in the general direction of being usable for some kind of game. With that said, the things you'll most likely end up having issues with is the general architecture of your engine, and scaling it up as needs grow. Making a pong clone doesn't require an engine at all. At most, it requires a FillRect function (my first ever game was also pong, and i did the entire thing using only the windows function FillRect, even the numbers). The smaller games need maybe a couple of functions for rendering, collision detection and that's it. That your engine. My advice would be to not set yourself up in the mindset of "i wanna be a pirate make an engine", but rather, just make the small games with the least effort possible. If you start going all enterprise software on those simple games, making a bunch of infrastructure that you don't need for them, progress will seem slow, you'll lose motivation, and abandon another project. The broad plan looks fine with games in sight, but just focus on building those games. Once you finish a game, start a completely new project, and copy over code that you can reuse to make the new game. Then when you finish the second game, start a completely new project, and copy over code that you can reuse from the second game. Rinse and repeat, and over time you'll just incidentally have grown an engine. And forget about multiplayer for the time being.That is a whole other ball game. Focus on making and being comfortable making single player games.
  2. Strewya

    Component Entity Design

    I don't think you need an entity for the game logic. Also, game logic doesn't have to be a component. You can put the game logic into main(). Process the input, update the placement of units according to game rules, and then render them at their positions. Also, a bit of a rant and personal opinion here, i think ECS is overkill for something like a checkers game. The ECS style architecture would be better suited when you have so many entities it becomes unwieldy to handle each of their behaviours individually (because you either duplicate a lot of code, or make large inheritance hierarchies where you can't reason about the code quickly anymore), so you split them into a smaller subset of pieces which you can easily [reason about it's] process/update, and compose the higher concept entities from those pieces, relying on standardized piece-wise functionality. And you can even continue the process further, and split any of those pieces (L1 pieces?) into another subset of pieces (L2 pieces) with their own update procedures, in order to compose the higher level piece, out of which you compose the entities. This is what you'd be doing anyway when you're coding for the first time, or not following ECS rules: embedding structs into structs into structs until you have a good data organization scheme that you can easily follow. Anyway, to follow the thread question, what i would do is something like the following (pseudo code): EMPTY = 0 RED = 1 BLACK = 2 board { Tiles[8][8] = {EMPTY} sprite BoardSprite sprite RedPiece sprite BlackPiece } int main() { // .. initialization of the window, device, state, whatever board Board GameRunning = true while(GameRunning) { Input = grabInput(InputDevice) GameRunning = gameLogic(Input, Board) render(GraphicDevice, Board) } } "grabInput" returns a struct with the inputs you want to handle (either raw device input you're interested in, or remapped logical commands, whatever suits your needs or framework). "gameLogic" receives the board and the input, and internally, checks if it's the red or black player turn, and either processes the user input into board actions, or lets the AI produce board actions, then executes the generated board actions for the active player (which at this point, the logic doesn't care if they were produced by the user or AI, you could use this to pit two AIs against each other). "render" just draw the board and the pieces, taking the visuals from the board. Since this is a very simple game, an ECS (as i said above) is overkill and too rigid in it's traditional definition. Chess expanded to 4 times the board size and piece count, with several new piece types, and done in real time, could maybe be a better candidate
  3. This is very much simplified, and purposefully so. class Object { RenderingData _renderData; ... }; int main() ... while(stillRunning) { stillRunning = updateGameLogic(allObjects); renderAllObjects(allObjects, renderer); } } The renderAllObjects function takes in the renderer interface, or a concrete renderer object, or whatever you have or want to pass in, grabs each object in the list and pulls out the render data (which can also be anything you want it to be, textures, models, buffers, shaders, etc), and passes it into the renderer in a renderer specific way. If you just need to decouple game logic and rendering, this is one way to do it, but not the only way, as i'm sure others will chime in with their ideas.
  4. Strewya

    Entity Component Systems and Data Oriented Design

    @Hodgman So i'm a bit confused, because i read (or understood) a few conflicting ideas from your post. These parts are conflicting in my mind: The last quote i understand is a main loop that updates arrays of objects. So how does it work? Do you updates arrays of Player, Monsters, Projectiles, CondumableItem etc, or do you update arrays of PhysicsData, InputData, CollisionData, RenderData, etc?
  5. Strewya

    Entity Component Systems and Data Oriented Design

    Could you maybe explain what you mean by hard-coding the entity types? Defining concrete c++ classes in code, rather than having a fully dynamic/flexible SoA style entity that can be anything and everything?
  6. That's because the expression &options return s pointer of type Options (or whatever the type of that struct of ints is), which when added to will produce an address that is offset by sizeof(options), which follows pointer arithmetic rules. A more correct version of your second loop could be: int* destinationInt = (int*)&options; for (int i = 0; i < optionsList.size(); i++) { int value = boolQuery(optionsList.back(), mem); optionsList.pop_back(); *(destinationInt + i) = value; } But this very much assumes your struct hold only ints and is a POD type (no vtable, hidden paddings etc). I hope you know what you're doing.
  7. A couple of years ago, i made a small game (a twin stick shooter) that sort of worked in a systems-update-component way, but wasn't a full ECS model. What i did was essentially a bunch of functions that each updated a specific subset of data. My entities were heavy and contained all data for that entity, but i had several vectors of data, one for players, one for projectiles, one for enemies, one for pickups, etc. And the control flow was all very obvious in the main gameplay function, just a bunch of functions calls that got passed in the data they required. updatePlayerPositions received the list of players and ran the logic that moved the players based on their direction, velocity, rotated them, and so on. updateEnemyPositions received the list of enemies, and so on, all the way up to the end of the gameplay logic. What i believe is that you should think of systems as nothing more that functions that receive the arguments required for the function to do it's thing. This way the subsets of data that needs to stand alone will become much more obvious and help you pull out and isolate only the parts that are really independant.
  8. I'll echo wintertime: the grass floor texture doesn't fit with the futuristic/military base look of the rest. Try some concrete textures with hazard yellow/black lines, or some such similar thing, at various places of the floor.
  9. Out of curiosity, could you explain your point of view?
  10. Strewya

    Depicting attack/spell ranges before movement?

    I'm working on a squad based, turn based game that has a similar issue. We solved it by making a look-ahead mode, where by pressing a button, you "project" the selected unit onto the tile you're hovering over, so you can see the attack range of your selected ability in the case you move your unit there. Releasing the button simply "cancels the projection". This way the player can check his ranges before commiting to the action, allowing him to tactically plan ahead.
  11. I'll just pop in to mention that the first approach Finalspace mentioned is the approach that Handmade Hero is doing, and the series is video documenting every step of the way. https://handmadehero.org/ https://hero.handmade.network/episodes
  12. I'd like to throw my pennies in the pile as well, which might echo Satharis a bit.   Your idea of making the systems run concurrently is, in my opinion, not a good idea. You should have a very clear and strictly defined sequence of operations that transform some data into other data. You input system transforms input messages into commands. You command system transforms commands into general actions. Your physics system transforms these actions into a position delta for your entities. As a purely output based system, the rendering system reads the positions, mesh/sprite data, and outputs them to the screen. None of these things can be run in parallel. Even audio might need information about an entity so it can play sounds at the correct 3d world position. And then you have animation systems that might have to be processed two times, once before physics, once after.   Your assumption in the first post that the systems are independent is thus not correct. All of these systems are dependent on another system, even your input system has a dependency (SDL). What you can do is parallelize the transformations within each system, so each object is transformed independently of one another.   So to get back to the question you posed: Send out each message immediately as it's ready, unless you want the message to be received at a later time, in which case you should be explicit about it and probably just process the message in the receiving system at that later time.
  13. Strewya

    Criticism of C++

    Note that i know almost nothing about Jonathans language except for one video i've seen a few years back when he first started working on it.   This only assumes the language itself doesn't provide you with mechanisms for pointer ownership. I recall from when i watched his first video that he wants to have a mechanism where the language and compiler themselves know that a variable is the owner of a pointer. Imagine it as having the unique_ptr as a built-in type, and not a template as well. As far as dot operator overloading, that is a valid question, one which is probably answered in one of his videos, maybe.   How do you easily and cleanly move lambdas that have captures? No idea if his language can do the same, so not sure the question is valid enough.     But anyway, you are using two different terms. Are you talking about preprocessing, which templates don't do, or compile-time computation? It sounds like you are talking about compile-time computation. If so, C++ added that back in 2011, using the 'constexpr' keyword. Initially it was (intentionally) limited in C++11, but they expanded it more in C++14, and intend to keep on expanding it to do exactly what you're talking about: Running arbitrary C++ code at compile-time to compute things, within limitation. Currently it's not fully unleashed, as they are gradually relaxing restrictions with each C++ release, to make sure any problems are ironed out and to give compiler developers a chance to catch up, and so programmers has a consistent featureset until it's fully present.   But the end result is the same, no? You get some automatic code generation done for you. In C, you have only macros to do things templates can do in C++. Granted, they both have their uses in C++, but it would help if you stopped looking at Johns language as an upgrade over C++, rather as an upgrade over C. As was mentioned in this thread, there's a smaller, simpler an easier language in C++ trying to get out, and that language is C. So why not improve C with some of the stuff C++ does better? Also, constexpr is very limited right now, and will probably stay limited to some degree. Johns language has no limitation. Sure, you'd have to control yourself and know that if you invoke an expensive function during compilation, it's gonna slow it down. But then again, you're a programmer, you're supposed to know the tradeoffs of doing so.   Again, the jumping to another file is solved by better tools. I can Ctrl+Click in the IDE I use, to jump between declaration and definition. Whereas there are arguable benefits for separating the two. Many C++ programmers argue the opposite extreme of what you are saying, complaining that a C++ class's private member variables are visible in the header.   Now, headers have other problems (mostly as a result of macroes, which are the reason many seemingly unrelated areas of C++ have taken so long to get fixed), but C++ is migrating towards a module system similar to Python's, which will solve alot of issues. Last I heard, the modules are supposed to get unofficially added to compilers in late 2017 or earlier 2018, and be officially standardized in 2020.   Sure you can jump easily with your IDE, but you'd have to jump less if we'd all just have the .cpp files instead of .h files, no? This might be the thing modules fix after they roll out, but i believe he was referring to having a java/C# model of just having one file type and the compiler figures out all the function names and symbols without you having to write a separate header file to include all over the place just so you can call a function cross files.   C++ is a general purpose language, and has it's flaws when it comes to certain domains, this much we can agree on, and it's been mentioned throughout this thread. As such it will never be perfect for game development. So why shouldn't we strive to have a language specifically suited for game development? Even if it's just C with some extra blows and whistles, some borrowed from C++, some invented to suit the needs of game development. Dismissing attempts to do so because we have something good enough... Well, the wheel got reinvented from time to time, didn't it?  
  14. Is it feasible to make both mechanics, and toggle between them through a menu option?
  15. Strewya

    Member function pointers?

    To be fair, casting a member function to a regular function is possible, but is usually not a smart thing to do because it depends on the compiler and if the function is virtual or not etc. class A { public: void Method(int x) { cout << x << endl; } }; void (Func*)(A* this, int x); int main() { A instanceA; Func f = (Func)(A::Method); //or some such evil cast, not sure if i'm missing and address operator, i.e. &A::Method f(&instanceA, 5); } However, if you're doing this, note that your code is bad and you should feel bad and change it promptly to a good design so you start feeling good because your code is not bad anymore. :)
  • 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!