Entity Component System | Coding a 2D Game Engine in Java #10

  Рет қаралды 28,223

GamesWithGabe

GamesWithGabe

Күн бұрын

Пікірлер: 121
@herlufbaggesen
@herlufbaggesen 3 жыл бұрын
This was really well put together! You explanation at the start was exactly what I needed to get some perspective about the different types of solutions. Thank you for making this video!
@GamesWithGabe
@GamesWithGabe 3 жыл бұрын
No problem Herluf! Thanks for watching, and I'm glad I was able to shed some light on different ways of implementing ECS :)
@onerimeuse
@onerimeuse Жыл бұрын
One, this is probably the best video I've seen yet on the actual structure and architecture of an ECS because it describes the "why" so well. And then you got to the programming bit. I was going to click off then, since I'm not advanced enough a programmer yet to watch someone program and get it usually... but you're describing the what and why in that as well. I'm only to component class, but because of your wonderful articulation of the details, I'm totally on board. Thank you for making such an awesome video!
@HendrawanDev
@HendrawanDev 4 жыл бұрын
Wow, finally a video about ECS! Let me craft my morning starter pack first, then i'll dive into it.
@GamesWithGabe
@GamesWithGabe 4 жыл бұрын
Haha yea, I figured it was time to finally start talking about it in terms of the engine that we're making. Unfortunately it's still very similar to the last one I coded, but I try to talk about the different methods and how you might implement them :D
@HendrawanDev
@HendrawanDev 4 жыл бұрын
Based on Component Pattern by Bob in his GameProgrammingPatterns site, he updates all components inside entity update, but he mentions this implementation is not correct in this video kzbin.info/www/bejne/gKmsZHiraqmDrac :v I agree with him, components should not be updated inside entity, and components with same domain should be updated in the same loop after another domain.
@GamesWithGabe
@GamesWithGabe 4 жыл бұрын
Hey Hendrawan, sorry about the late response, I don't get notified about replies :(, but I agree with you that the components with the same domain should be updated in the same loop. The reason I don't implement it that way is because this tutorial is in Java, so we have no control over where the components are being placed in memory. That means that even if we update each system (instead of each entity then all the components) it won't help much because we have no guarantee that the systems will have components placed next to each other. I am planning on doing some tests pretty soon in C++ to see what kind of performance gains you can achieve using his method, and I want to give a tutorial in the future about writing game engine in C++ so that we can implement these performance gains :D
@GamesWithGabe
@GamesWithGabe 4 жыл бұрын
Hey Hendrawan, I wrote up a simple ECS benchmark test in C++. I ran the test as if a player had played a game for 30 minutes at 60 FPS, and it was a game that consisted of 10,000 entities with 4 components each. The results I got were: 1.) If you don't use ECS, and just allocate random memory and iterate over it, you get an average of 983 microseconds to update all entities in one frame. 2.) If you use ECS (I allocated 100mb of memory, and stored the components right next to each other, then iterated over each component and updated) you get an average of 680 microsecond to update all entities in one frame. I'm not happy with this result though, because a real game is way more complex and the only way to truly test this would be to build the exact same game using ECS, and not using ECS. I plan on doing a longer term test and making a video about the results in the future. Let me know if you want access to the benchmarking code I used and I can upload it to Github and send you a link :D
@HendrawanDev
@HendrawanDev 4 жыл бұрын
No notification for boring comment :v I didnt even know that java behave differently than C++, i should learn more about memory in java. There are good reasons by putting each components with same domain in one system though, 1. Order is matter when updating components, like input for movement should be placed in the first row, then physic and then graphic, with system we can make sure all components can be updated in correct order. 2. Reducing gap between component of each entity, ex there A - Z entities, each entity has 4 components, and we update all components of one entity after another, the gap between component number 4 of entity A and entity Z is farther than if we put each components with same domain in one system. The farther the gap, the more weird will be. Give me the link please :D Curious about ecs in C++
@whatunoaboutit
@whatunoaboutit 4 жыл бұрын
Glad you chose to make this series. Very informative!
@BudgiePanic
@BudgiePanic 3 жыл бұрын
These videos have been really good, rivalling actual undergrad course on software design
@GamesWithGabe
@GamesWithGabe 3 жыл бұрын
Hey PineApple! I appreciate the comment, and most of my undergrad courses felt the subpar as well, but the textbooks that were assigned for the courses were usually very helpful :). And it also depended on the professor haha
@davidmarinho2848
@davidmarinho2848 3 жыл бұрын
Me when video starts: Finally! Something that is very familiar to me. Me at 1:52 of the video: Ok... It's better to pick my notebook. Hey Gabe, I am enjoying lot your tutorial series. I am learning many new things, not just about LWFGL, but also about new games' concepts that I have never heard talked about before (for example, in my games I usually use the first method that you talked about at the beginning of the video, at least until today, because that method of doing that seems very interesting and just better ahahah). And it's incredible how your half-hour of content takes me 1-2 hours. Please, just keep going with the series, you are making an incredible job and helping a lot of people. Thanks :D
@GamesWithGabe
@GamesWithGabe 3 жыл бұрын
Hey David! Thanks for the comment, I really appreciate the support and I'm glad that the content is helping you learn about new techniques. I'm also learning new game design techniques everyday and hope I can share them with you guys. I definitely don't see myself running out of video ideas anytime soon, so I should be able to keep the series going :)
@davidmarinho2848
@davidmarinho2848 3 жыл бұрын
@@GamesWithGabe You are welcome, you deserve it! Nice! It's important to invest in studies almost every day and you are doing a great job in that field. I am also willing to see all your series xD. P.S.: Also enjoying a lot your geometry dash series :D.
@thesuitablecommand
@thesuitablecommand 9 ай бұрын
Hey! I'm loving this series so far. I tinkered a bit with LWJGL back in college in my spare time but it never really settled in my mind. This tutorial series is doing a great job of explaining how everything works under the hood along with how to actually code it into the program. Very informative stuff and I appreciate it a ton! One Q though, if you're still checking comments here... the 'jade' package. Is that just a name you made up? Is it a term for something specific? What does it mean, and what is it intended to encompass?
@GamesWithGabe
@GamesWithGabe 9 ай бұрын
Thanks for the comment! It’s just a name I made up for the engine :)
@thesuitablecommand
@thesuitablecommand 9 ай бұрын
@GamesWithGabe thanks for the reaponse! I'm taking a stab at making a D&D-like game, using a Pokémon-like aesthetic. I already wrote a library for the D&D mechanics, and I'm trying to make a graphical client for that code now. I am excited to see how much I'll be able to achieve, and your tutorial feels like it's going to provide a great launching-off point for my purposes :)
@hyperocket3279
@hyperocket3279 4 жыл бұрын
This was pretty interesting... now I understand why low level languages are soo glorified. Learned some new java stuff to :)
@GamesWithGabe
@GamesWithGabe 4 жыл бұрын
Thanks Hype Rocket :)
@lengors7327
@lengors7327 Жыл бұрын
Heyo, late to the party Gabe, but a few notes/opinions of mine for this topic: - First, I still think there are advantages in using a purely data-driven ECS even in Java, despite not being able to control the memory layout of the data. The first is that you have good separation of concerns (aka Entity will be a reference/id, Components will be associated with the Entity and contain all the relevant data but won't have any responsibility of performing some computation and Systems will have that responsibility instead) The second advantage is that it's much simpler to write multithreaded code with an actual ECS implementation rather than GameObject-Component one (Ill call it GOC from now on). On the GOC one your functions (for example the update) will run from every component. This means if you wanna start a thread pool and execute the same computation (lets say perform the euler method on a physics engine) for each component you will either have to make the first component start the pool and communicate between each component instance so the others don't start the pool and on top of that you will have to make it fetch all the other components of the same type to submit them and finally wait on all of them to finish or, alternatively, you could add a way to annotate component types and functions to tell your scene whether to perform the update on a thread pool or sequential (or some other form of parallelization). On the other hand, if you go with a ECS approach the system (in the example, physics system) can just query for all rigidbody components, and perform the Euler method using for instance a parallel stream map function which simplifies immensily the process of parallelizing the computation. On top of that, the system would be responsible for starting any threads it needs (if it needs something different from a simple stream map) rather than having to pass flags around or worst, make the code extremely complex if you go with the first approach. - Second, and this is just a personal belief, but I don't think Entities/GameObjects should ever have to have components added/removed after they are initialized. Rather the components themselves should be design in such way to allow for whatever dynamic data is necessary. But, I can see how having it can be useful at times
@arnetriesyoutube
@arnetriesyoutube 2 жыл бұрын
This was really helpfull! Also very well explained, although i don't get why people are calling you out for not using ecs instead of ec. I think you explained your reasoning very well. Oh and i'm impressed that you are taking the time to answer those comments here and give some sources where to further ones studies. I think that shows great charakter.
@mwbgeometrydashpcaccount6372
@mwbgeometrydashpcaccount6372 3 жыл бұрын
18:43 my spine shivered because it made a weird sound just like in one of the geometry dash videos
@beaumanVienna
@beaumanVienna 3 жыл бұрын
Very well explained, great presentation, nicely done!
@AdityaSinha92
@AdityaSinha92 3 жыл бұрын
incredible explanation. Thank you!
@smokeythebear1633
@smokeythebear1633 2 ай бұрын
At 28.05 when following along I get the error "Non-static method 'getComponent(java. lang. Class)' cannot be referenced from a static context" Any ideas?
@luandkg
@luandkg 4 жыл бұрын
Wow, amazing 😍 😍😍
@GamesWithGabe
@GamesWithGabe 4 жыл бұрын
You're support is awesome Luan! :D
@GarrethandPipa
@GarrethandPipa 2 жыл бұрын
I am not a big java guy but... arraylists are not contiguous but arrays typically are because you allocate there size on the stack thusly int[] enityIds = int[200]; It works because they are immutable. arraylists are just fancy linked lists with decorators but their undepinning are still an array of pointers to memory that is not contiguous. Additionally referencing your components to entities the components store the index to the entity and the entity stores the indexes to its components called double indexing. When you remove an item form one of the arrays you pull the last item of that array and push it to the now vacated spot updating the new index. This in my opinion is the hardest part to wrap your mind around and implement.
@GamesWithGabe
@GamesWithGabe 2 жыл бұрын
Hey Jeff, as far as I'm aware I believe even regular java arrays are just arrays of pointers (unless it's a primitive type). So it's not really possible to get objects in contiguous memory unless you do some hacky code like using a wrapper around some native C code that gives you some raw memory (I think lwjgl does stuff like this). This SO answer seems to give a pretty good overview stackoverflow.com/a/51603427 . And this indirect indexing method that you're talking about is the traditional way of implementing most ECS :). The guy who wrote the entt library has some great articles called, ecs back and forth, or something like that where he talks about some of the fundamental data structures that you can use for this, like the sparse set. It's definitely worth a read :)
@slavsquatsuperstar
@slavsquatsuperstar 3 жыл бұрын
Do you ever just watch too many videos on ECS and go, "Isn't 'component' such a weird word?" xP Thanks for the great video, by the way. I was really hoping to find a Java implementation.
@GamesWithGabe
@GamesWithGabe 3 жыл бұрын
Haha thanks for the comment Eric! And I've thought about trying to code a Java ECS, I just haven't found the time yet :)
@jestry2508
@jestry2508 3 жыл бұрын
I enjoyed it once again :)
@DaniilBubnov
@DaniilBubnov 3 жыл бұрын
Also (sorry for being picky) this is not a canonical ECS approach. It should be: components - data structured with no behavior, systems - functions with no state
@sorensaket
@sorensaket 2 жыл бұрын
The naming here is weird. The thing he is making is an Entity Component system. Not an ECS system or Entity Component System system. There are huge differences between the two and should not be confused with eachother. They are fundamentally different and the naming is unfortunate.
@User-oh8vi
@User-oh8vi Жыл бұрын
Do you have a source that explains what the canonical approach is? I'm not sure if the resources i've found are correct
@Snowmanver2
@Snowmanver2 2 жыл бұрын
amazing and interesting~
@frankpoth154
@frankpoth154 3 жыл бұрын
There are articles out there that emphasize adding/removing components on the fly, but I agree that a lot of games I enjoy would never need to do this and I have a hard time thinking of a need for it. Adding/removing buff components would be a good case for this, however. I'm sure it's very useful, but it's difficult to implement - at least for me.
@GamesWithGabe
@GamesWithGabe 3 жыл бұрын
Hey Frank! I'm pretty sure I end up adding this later on in the series. If I don't add this in this series though, the way I would do it is by making a queue of components that are marked for removal. Then at the end of the frame you could destroy all the components that are queued for removal. That way you don't have any concurrent modification issues :)
@elessarIT
@elessarIT 2 жыл бұрын
Nice work! Can u please explain why inside the Font renderer you search if the game object has a sprite renderer and if so you print out "Font renderer found"? It is a typo?
@Clarsachh
@Clarsachh Жыл бұрын
I was wondering about the same.
@thesituation5315
@thesituation5315 Жыл бұрын
Hi, I'm not sure if you'll respond but I have a question that I'm very confused about. I've been following this and the physics series. I see that your Rigidbody extends Component, but I'm wondering what the Rigidbody's parent gameObject should be?
@jonispatented
@jonispatented Жыл бұрын
The rigidbody's parent GameObject should, of course, be whichever GameObject has the rigidbody. For instance, if you have a boulder that should have a rigidbody, then that boulder GameObject should be the parent of that rigidbody.
@aaronshed
@aaronshed 2 жыл бұрын
You can control specifically how things are placed in memory, if you use an unmanaged language. You also didn't make an ECS system, you made a traditional OOP system
@monkey5266
@monkey5266 2 жыл бұрын
So really ESC isn't really possible in java because of the garbage collector.
@aaronshed
@aaronshed 2 жыл бұрын
@@monkey5266 You actually can, Java allows the use of unsafe code. I personally wouldn't recommend it though, you might as well use c or c++.
@roamingcelt
@roamingcelt 11 ай бұрын
In removeComponent you have a loop. That loop only runs to the first instance of that component before returning. Why? This doesn't make sense.
@Ilumar589
@Ilumar589 4 жыл бұрын
Great video. My advise to you if you plan to use the framework and it's not just educational is to write it directly as an ecs and not just ec. Yes, you don't have control over memory layout in java but that's not what you need, you just need control over continuous memory, that can be done via primitive arrays, byte buffers(on and off heap) of using unsafe directly. That being said it won't be idiomatic java so just write arrays of classes and use them as you would primitive arrays because when project Valhalla is finally done you can just add the inline keyword to the classes that act only as data and you will get the desired memory layout. Anyway, you got a new subscriber, keep up the good work!
@GamesWithGabe
@GamesWithGabe 4 жыл бұрын
Thanks Eduard! I do agree with you that using ECS is better than just EC (and it's actually what I'm doing in my engine that I'm working on off-video), but I think if you're gonna do the ECS you may as well do it in C++. I think that because if you want that much control over memory layouts and stuff, you may as well do it in a closer-to-the-metal language, but I definitely see your point too and it might be interesting to see the effects it would have on performance in Java. Perhaps I'll try modifying the Java engine one day to see :D
@Ilumar589
@Ilumar589 4 жыл бұрын
@@GamesWithGabe There is nothing inherently faster in modern C++ compared to Java except for value types, if you want performance/lack of fragmentation you still need to do C style custom memory allocators. Honestly for indie games it's not worth the hassle. Between project Valhalla, Panama and the new low latency GC's you can get all the memory layout options and performance you need. Of course if you plan to release on consoles then you have no choice but to go the C++ route. Btw, you can try Rust instead of C++, much more coherent language. All the best on your journey!
@GamesWithGabe
@GamesWithGabe 4 жыл бұрын
@@Ilumar589 Thanks again! I definitely agree with you on the performance aspect, I differ on a couple points, but that's just my opinion haha. I have heard a lot about rust and I need to give it a try at some point, I'm actually starting to like C++ (which kind of scares me lol), but I do like learning about new languages and approaches :)
@cradledani
@cradledani 4 жыл бұрын
This looks very interesting. Sub'd so i can follow your progress on this series.
@GamesWithGabe
@GamesWithGabe 4 жыл бұрын
Thanks Atomizer! Every sub helps a bunch :D
@Speiger
@Speiger 3 жыл бұрын
Dunno if you see this comment. But LWJGL3 has a class called StructBuffer which allows you to actually use ByteBuffers in a way where you can make ECS possible within Java. Since you can allocate memory like that quite easily.
@GamesWithGabe
@GamesWithGabe 3 жыл бұрын
Hey Speiger, yep you can do ECS in Java if you want to, but I feel like ECS is a pretty low-level optimization where you're trying to get the best out of your memory layout. Java was purposely created to abstract memory away behind a garbage collector, so I feel like this is more a question of using the appropriate tool for the job. C, C++, and Rust are big languages that are very concerned with providing access to low-level memory management. So, if you want to implement something like ECS I feel like it would be better implemented in one of those languages :)
@Speiger
@Speiger 3 жыл бұрын
@@GamesWithGabe "Better in other languages" true won't deny that. But LWJGL3 gives you access to native memory which technically is not controlled by the garbage collector (the ones that LWJGL3 provides) so technically with that you COULD work with that. And their memory allocator is insane fast... You forget that fact, and that would also allow you to align these values in a byte array which you get full control over. I mean memory alignment you have not much control over but BUT if you allocate 100MB of a byte[] you can be pretty sure its fully aligned. That means if you do wizzardry with byte[] to your data structures then you could achieve the same thing. LWJGL3 just gives you the tools to achieve the same thing easier. Point: Its not impossible, just annoying, other languages make it easier xD
@andraantariksa4027
@andraantariksa4027 4 жыл бұрын
Can you elaborate on what you have said in 8:15 , you said it's stupid if we do ECS pattern because arrays layout are not guaranteed, isn't Java have the same feature as C/C++ for this case?
@andraantariksa4027
@andraantariksa4027 4 жыл бұрын
I mean you can use stack allocated array for that
@GamesWithGabe
@GamesWithGabe 4 жыл бұрын
Hey @Andra Antariksa , so I got asked a similar question awhile ago and found this Stack Overflow thread which references the JVM documentation stackoverflow.com/questions/10224888/java-are-1-d-arrays-always-contiguous-in-memory (the first two answers are the most helpful). They both basically say that since Arrays are implemented as objects, and the JVM places objects on the heap, and any data on the heap may not necessarily be contiguous, then arrays are not guaranteed to be laid out in contiguous memory. The main point I was trying to make though is that if you want low-level control over your data, you should probably be coding it in C++ where you have complete control over the data. Whereas trying to implement it in a language like Java involves a lot of guess work because it's very difficult to know exactly how and where your data will be laid out in memory, and exactly when the memory will be cleaned up etc. In terms of a stack allocated array, I'm not sure if you're referencing a special class that I haven't used, but in terms of regular arrays in Java, there is no way to allocate the memory on the stack, since once again they are implemented as Objects. I hope that helps a bit, if I misinterpreted any part of your question, or I raised more questions feel free to let me know :)
@andraantariksa4027
@andraantariksa4027 4 жыл бұрын
@@GamesWithGabe thank you for your quick response! I actually want to implement ECS in Crystal language, not in Java. I watch your videos to get an insight to implement ECS architecture in garbage collected language. In Crystal they had stack allocated array, will it solve the problem?
@GamesWithGabe
@GamesWithGabe 4 жыл бұрын
@@andraantariksa4027 no problem! As for the Crystal Programming language, I have not used it, but from my brief look into it, it looks like it is also a garbage collected language. (Correct me if I'm wrong) If it is, then you can certainly try an ECS approach, but not having direct control over how the data is laid out in memory won't help very much when it comes to implementing it. For some good articles on how to write a good ECS, I highly recommend these: skypjack.github.io/2019-02-14-ecs-baf-part-1/ it's written by the guy who created entt (an entity component system that is very successful, it's even used in Minecraft :) )
@DaniilBubnov
@DaniilBubnov 3 жыл бұрын
Hi, thanks for the informative video, I have a question. I was watching ECS realated video and there ppl were also talking about cache misses and performance issues. Is it a real thing? Asking because I haven't found or seen any comparison to understand how important it is to keep the relative data closely to each other instead of just having them all over the heap
@GamesWithGabe
@GamesWithGabe 3 жыл бұрын
Hey Daniil! I'll try and respond to both your comments here briefly. I'd like to mention first that you are completely correct when you say this isn't an ECS approach (it's more of a "C"omponent only approach haha). This video was just to show what ECS is, and how to implement a component pattern that is useful for decoupling behavior from state. I didn't attempt to build true ECS in java, because if you are trying to build ECS, its better to do it in a low level language like C++, C, or Rust so you have direct control over memory layouts. In regards to whether ECS does help performance, and can reduce cache misses, I think that's debatable because modern hardware has so many different factors it's hard to say whether one change like this can reduce a cache miss or not. There is a very good video on this that Mike Acton does, and he gives a sample C++ program to demonstrate the potential performance increase in using ECS. However he reduces it to a trivial case, and the performance difference only becomes critical only when you have a very large amount of active entities (like 10s of thousands) which may not be present in an indie game. I'll reply to this comment once I find the video if you want to check it out (my ISP is down right now so I have limited internet access) 🙂
@DaniilBubnov
@DaniilBubnov 3 жыл бұрын
@@GamesWithGabe wow, thanks for the detailed answer. I have watched some of the Mike's videos on ECS and now see what scale of performance is considered in data oriented way of ECS
@GamesWithGabe
@GamesWithGabe 3 жыл бұрын
@@DaniilBubnov great I'm glad you were able to watch some of them! And no problem man, I hope you're able to find a solution that works for you :)
@ivansantiago3458
@ivansantiago3458 2 жыл бұрын
In data-oriented programming, if some entity has more than one box collider wouldn't there be a problem? How could it be solved?
@GamesWithGabe
@GamesWithGabe 2 жыл бұрын
Yea typically most entity component systems don't allow multiple components of the same type for one entity. You can usually get around this by just creating some sort of parent-child component for entities, and then adding a child with the extra component. You could probably even do this all behind the scenes in code so the user just feels like you can add multiple components of the same type per entity, but it's really adding new children with the component
@Bandit-is8zi
@Bandit-is8zi 10 ай бұрын
8:03 We can block the road so the garbage truck cant come to pickup garbage :)
@eskevv446
@eskevv446 Жыл бұрын
So the ECS architecature if mostly for performance or convenience? Since you say it doesn't really suit Java as well as c++ for example, can we still justify it's use in garbage collected langauges? This confuses me because I thought even in Java elements in an array are all contiguous in memory, so why can't we also just pack the components together in arrays of arrays? Thanks for this awesome series Gabe, I'm really enjoying it :)
@GamesWithGabe
@GamesWithGabe Жыл бұрын
Going full ECS is typically done for performance reasons. Chunking up the data related to your game object into smaller pieces (components) is helpful for your CPU cache since it can fit more of them in L1, L2 or L3 cache without having to hit main memory. ECS does have a useful way of thinking about architecture though which is often parroted in the Java community as, prefer composition over inheritance. When people say this, they're basically saying to make something like an ECS because it makes code easier to reason about. In Java it's not really worth it to put all your objects in the same array, because it's not guaranteed to be contiguous in memory. It actually sounds like it probably won't be to reading through the spec here docs.oracle.com/javase/specs/jls/se19/html/jls-10.html . It talks about how cloning an array makes a shallow copy, and how an array of type T[] will store a reference of T. This implies that the arrays don't store the data itself continuously, but rather pointers to the objects (which is fine because the JVM is modelled to deal with this and has some performance tricks to help out). So I would say it's not worth it to store everything in arrays and try to micromanage your memory because it likely won't work out in Java. Hopefully that clears it up a bit, but it's a great question and I'm not completely sure how the JVM will handle all this. So, as always, you should profile your code to see where the true bottlenecks are if/when performance is a problem :)
@eskevv446
@eskevv446 Жыл бұрын
@@GamesWithGabe I was reading about how Java stores references as well, and why objects still end up getting moved around in memory even inside of an array, which results in those cache misses we try to avoid. The gargbage collector basically wants to keep all heap memory compact to make allocation easier. But this is honestly the perfect answer in such a short amount of time. Thanks 😄
@sconosciutosconosciuto2196
@sconosciutosconosciuto2196 4 жыл бұрын
New sub :D
@GamesWithGabe
@GamesWithGabe 4 жыл бұрын
Thanks Sconosciuto! :D
@asherhaun
@asherhaun 4 жыл бұрын
how do I change gameObject values, I attempted to change the Transform property with a setter "setTransform(Transform t) {transform = t}" and although it does update the transform, I don't see the position change (fyi, I am a few videos ahead, so I just finished the batch renderer)
@GamesWithGabe
@GamesWithGabe 4 жыл бұрын
You may want to take a look at the dirty flags video, I think it's the next video or so. I would also recommend being wary of assigning objects like that. When you pass in the entire Transform object and say transform = t, you're not making a copy of that transform, but rather reassigning a reference. This article looks like it explains this concept pretty good javarevisited.blogspot.com/2015/09/difference-between-primitive-and-reference-variable-java.html . Whenever I want to copy a transform's values, I typically create a function that does something like Transform.copyValues(Transform from, Transform to) and then just copy all the floats, that way you retain the original transform and just copy the values.
@asherhaun
@asherhaun 4 жыл бұрын
ok, that sounds reasonable, thanks. even still, it doesn't update the visuals
@GamesWithGabe
@GamesWithGabe 4 жыл бұрын
Yea, copying it may not update the visuals because you still need to upload the changes to the GPU by updating the VBO that contains the draw data. The dirty flags episode is about solving that, let me know if it still doesn't update after implementing that portion :)
@asherhaun
@asherhaun 4 жыл бұрын
Alright, I will get back to you on that, thanks!
@syntaxed2
@syntaxed2 3 жыл бұрын
When referring to JAVA as a "garbage collected language" I sometimes like to omiss the middle word :D
@GamesWithGabe
@GamesWithGabe 3 жыл бұрын
Lol, I would tend to agree, but unfortunately the more I work with other languages I feel like that could be said about all of them :)
@syntaxed2
@syntaxed2 3 жыл бұрын
@@GamesWithGabe So true :D anyways, good contents on this channel!
@huangwilliam9880
@huangwilliam9880 2 жыл бұрын
Do you think using a Set is better than a List for storing Components? I don't see how the order of Components matters for a game object.
@TheBEstAltair
@TheBEstAltair 2 жыл бұрын
Sets can't contain duplicate elements though. Wouldn't that be then up to the Equals methods of Components on whether 2 very similar Components can be placed in the same set? With List you don't need to worry about it...
@huangwilliam9880
@huangwilliam9880 2 жыл бұрын
@@TheBEstAltair alright, thanks for telling me.
@hrithikverma2761
@hrithikverma2761 4 жыл бұрын
Dear can you help me I wanna develop games how do I get started. I am completely a beginnet
@hrithikverma2761
@hrithikverma2761 4 жыл бұрын
Please help sir. 😊😊😊😊
@GamesWithGabe
@GamesWithGabe 4 жыл бұрын
Hey hrithik, if you have no experience programming, I have a beginner programming course playlist that you can follow. If you already know how to program in Java, I would suggest starting out with my Pong or Snake series, they start out by building games and not worrying about game engines. Some good resources that I used when I was first learning to program games are these: * www.amazon.com/Foundation-Game-Design-HTML5-JavaScript-ebook/dp/B00ACC6AU0/ref=sr_1_fkmr0_1?dchild=1&keywords=game+design+rex+van+der+spy&qid=1588352785&s=digital-text&sr=1-1-fkmr0 * www.amazon.com/Advanced-Game-Design-HTML5-JavaScript-ebook/dp/B01JCM6SXY/ref=sr_1_fkmr1_1?dchild=1&keywords=game+design+rex+van+der+spy&qid=1588352844&s=digital-text&sr=1-1-fkmr1 * gameprogrammingpatterns.com/ And another great KZbin channel that helped me: * kzbin.info/aero/PLRIWtICgwaX0u7Rf9zkZhLoLuZVfUksDP After you have a basic knowledge, I would suggest just trying to make a game, and then you'll start to see where you will need more help. Let me know if I can help you out in any other way! :D
@denvercox7675
@denvercox7675 3 жыл бұрын
So you cant do a true entity component system in java because the arrays are not guaranteed to be continuous? Recently I have heard of a class called "Unsafe" which as its name suggests is not safe, but it has a method that allows dynamic allocation of memory, similar to C's "malloc" method. do you think this would allow a true entity component system in java?
@GamesWithGabe
@GamesWithGabe 3 жыл бұрын
Hey @Denver you can definitely use something like this to create an entity component system in Java :). The only problem I have with doing something like this is that it feels like you're working against the language to get the job done. Whenever it starts feeling like I'm fighting the tools I'm using to do something, I ask myself if I'm using the right tool for the job. I think that was more of the reason I said I wouldn't consider making an ECS in Java
@denvercox7675
@denvercox7675 3 жыл бұрын
@@GamesWithGabe yeah that makes sense, thank you for your reply!
@GamesWithGabe
@GamesWithGabe 3 жыл бұрын
@@denvercox7675 No problem :)
@lucd9642
@lucd9642 3 жыл бұрын
Great episode, as always! But I'm wondering why don't you make deltaTime a variable in Window? Then instead of passing deltaTime to all update functions you can just get it by something like Window.get().deltaTime()
@GamesWithGabe
@GamesWithGabe 3 жыл бұрын
Hey Luc! You could definitely do it that. I like passing it in because I don't like calling Window.get() and using it as a singleton. I've actually moved completely away from this style of programming in my personal engine (and away from OOP in general), but there's nothing wrong with getting the value that way as well
@therunnerproject
@therunnerproject 3 жыл бұрын
Nice explanation for ECS, it's just a shame that you only implement the component pattern in the end, due to the limitations of Java.
@GamesWithGabe
@GamesWithGabe 3 жыл бұрын
Thanks! And yea you can still make one in Java if you would like, but it's a bit easier to work with memory in a lower-level language like C++. I found a great tutorial for C++ ECS though if you're interested www.david-colson.com/2020/02/09/making-a-simple-ecs.html :)
@therunnerproject
@therunnerproject 3 жыл бұрын
@@GamesWithGabe Thanks. I am currently working on an ECS with C#, there you also have the opportunity to work with pointers and unmanged memory. Unity also created their ECS entirely in C#.
@GamesWithGabe
@GamesWithGabe 3 жыл бұрын
@@therunnerproject Yep C# is a much better language to use when you want to deal with lower-level memory stuff. Good luck with your project though :)
@oftenyoutuber4348
@oftenyoutuber4348 2 жыл бұрын
18:43 there's a weird sound
@boombvss
@boombvss Жыл бұрын
This video doesn't support subtitle translation. 😔
@BrandonLamb1
@BrandonLamb1 4 жыл бұрын
Trying to understand if ECS is understood here. The java code doesn’t seem to be an implementation of ECS. Components should not have functions/behavior, basically just a struct. This felt like copying unity gameobject style. I guess the title of this video may mislead someone into thinking this is an example of a proper ECS implementation, which is where I was left scratching my head. Also curious on the accuracy of Java arrays not using contiguous memory, might be something to google next. Am I understanding this video is really not ECS but about implementing a component style architecture? Seems like a step up from OOP inheritance tree but on par with what unity is already working on replacing with proper ECS, which they claim big performance improvements which should also apply to JVM as both are GC managed languages? Interesting video still!
@GamesWithGabe
@GamesWithGabe 4 жыл бұрын
Hey Brandon, thanks for the comment! This Java code that I write in this video is definitely not ECS, but rather the Component Pattern as outlined in the gameprogramming article in the description. I also mention that I won't be employing ECS in the code because Java is garbage collected, and we have no control over memory space. On my comment about the Java arrays not using contiguous memory, I didn't mean a single array would not be contiguous in memory, but that two arrays declared next to each other may not be contiguous. However, I came across this link which suggests that even arrays may not be contiguous: stackoverflow.com/questions/10224888/java-are-1-d-arrays-always-contiguous-in-memory Also, Unity is working on ECS, but the reason that they can implement it in C# is because they have written their own compiler, the Burst Compiler. This means that they are directly controlling how the C# gets compiled down to machine code, which also means that they still have control over how the memory is being laid out. You can read up a bit more about that here: blogs.unity3d.com/2019/02/26/on-dots-c-c/ Once again thanks for the comment, and for thinking critically about what I propose in the video! The last reason that I have not tried to improve the pattern that I use in the video is because it's simple conceptually, fast enough, and it works. If the game you're writing suddenly starts losing frames, I think profiling is the way to go to see what the performance critical part of your code is :)
@BrandonLamb1
@BrandonLamb1 4 жыл бұрын
GamesWithGabe hmm interesting, definitely something I’m interested to try to find out more on. I’ve been trying to soak up as many videos as I can on this stuff, it’s super fascinating. I’m using Godot but wanting to make a multiplayer server in java or rust and code organization is an important piece to get right. Thanks again for video, also recommend checking out kotlin, makes some of this code much easier/concise. Cheers!
@BrandonLamb1
@BrandonLamb1 4 жыл бұрын
GamesWithGabe curious, even if not stored contiguous in heap wouldn’t you still gain performance by not pulling your entire player object as you would fill caches more likely as part of the benefit is only pulling the data needed.. if you request 100 monster objects that contain all components, jvm or cpu will pull the entire memory they use assuming you will use it when you only may be using transform? Seems like you may still gain benefit. Still reading that SO article, good stuff
@GamesWithGabe
@GamesWithGabe 4 жыл бұрын
Hey Brandon, I would assume you would still get some performance gain, however I'm not sure how much haha. I did some tests with a fake "game" where I simulated a player playing for 30 minutes at 60FPS using ECS, and then the same code without ECS, and I was consistently seeing a performance improvement of about 300 microseconds (I wrote this test in C++, the repository is here if you wanna take a look github.com/ambrosiogabe/ECSExperiments). I'm not sure how accurate my test is, since it's not an actual game, (and I don't even know if I coded the ECS part right, I'm still learning too haha), but I definitely want to do a test in the future where I code the same game twice, once with ECS and once without it to see what kind of performance benefits there are because I haven't been able to find any good benchmarking suggesting that using ECS will give a huge performance gain. Also, I will definitely take a look at Kotlin, however I have been planning to switch to C++ pretty soon, so I may not end up using it haha. And, good luck with your project! It sounds super interesting and I've been wanting to dabble in multiplayer for awhile now, so let me know how it goes :)
@sconosciutosconosciuto2196
@sconosciutosconosciuto2196 4 жыл бұрын
How can you destroy a Gameobject?
@sconosciutosconosciuto2196
@sconosciutosconosciuto2196 4 жыл бұрын
With a function like destroy()
@GamesWithGabe
@GamesWithGabe 4 жыл бұрын
Hey sconosciuto, I found that the best way to destroy game objects is by having a list called objectsToDelete, then you can call Scene.destroyGameObject() and add the game object to the list. Then at the end of the frame, you remove all the game objects that are pending to be deleted. If you just wanted to call gameObject.destroy(), you could do something similar where you set a flag on the game object that says shouldDestroy = true, then at the end of the frame remove it from the game objects list. The reason I suggest waiting til the end of the frame is because you could have issues with concurrent modification. I have an example that you can look at here: github.com/codingminecraft/Mario/blob/master/src/main/java/com/jade/Scene.java in the function deleteGameObject :)
@sconosciutosconosciuto2196
@sconosciutosconosciuto2196 4 жыл бұрын
@@GamesWithGabe ok thanks, but there is a problem. I can't store the reference to a gameObject anywhere else. For example in another component I can't store a GameObject reference to another gameobject (a component that uses a pathfinding algorithm to search the path to another GameObject for example). Because otherwise it wouldn't be destroyed by the GC and the component would search a path to a Gameobject that should be destroyed.. The same problem exists with components (I can't store a component reference inside another component) Probably I'll switch to C++
@GamesWithGabe
@GamesWithGabe 4 жыл бұрын
Hey Sconosciuto, this problem will persist in C++. There are different design decisions that you could make to try to alleviate this problem, but you will always have to check if the gameObject/component still exists if you are trying to store references to it. Check out these stack overflow questions: gamedev.stackexchange.com/questions/148833/how-to-handle-entity-initialisation-and-destruction gamedev.stackexchange.com/questions/115580/how-to-handle-gameobjects-that-have-been-destroyed-but-are-still-held-by-others You'll notice that one of the answers in the second question says that you can do a system like the one I suggested, where the entity is removed at the end of the frame in a clean-up step if it gets destroyed, to prevent errors within the frame. But, you will still need to check for null objects. This problem even persists in professional game engines, take a look at these questions about Unity and Unreal: answers.unity.com/questions/1688939/code-still-trying-to-access-object-that-has-been-d.html stackoverflow.com/questions/58997811/ue4-how-can-i-detect-if-an-actor-refrence-has-been-destroyed-in-blueprints So, I would advise in trying to find a different solution for the specific problems your suggesting. Perhaps make a copy of the position of the entity you are trying to pathfind to, and if that entity is destroyed I think that it would be an error anyways if your AI tried to continue to pathfind towards it. I'm planning on switching to C++ myself pretty soon, but it's because I want to learn more about low-level memory management and see if I can improve performance. Problems like this will still exist in C++, they will just take on different forms :)
@sconosciutosconosciuto2196
@sconosciutosconosciuto2196 4 жыл бұрын
@@GamesWithGabe ok :D
@jimraynor3767
@jimraynor3767 2 жыл бұрын
This is very good, but I get monkeypox from that gay background music
@oftenyoutuber4348
@oftenyoutuber4348 2 жыл бұрын
FUN FACT: This video was published on my 11th birthday! But now I'm 13
@makispapa5867
@makispapa5867 2 жыл бұрын
Why not just use HashMap.newHashSet for your components and just iterate like for (Component c : components) instead of for (int i=0; i < components.size(); i++). Makes more sense to make components thread-safe in a game engine.
@GamesWithGabe
@GamesWithGabe 2 жыл бұрын
You can't have two components of the same type with a hash set which is why I used a regular list. Also, HashSet isn't thread safe on insert or removal. And if it was, you would have to do some heavy modification with some plans on how to support a multithreaded logic update loop for your game engine :). I think most modern game engines prefer to multithread large systems like physics, audio, rendering, input, ai, etc. Instead of multithreading at such a granular level to avoid synchronization costs as much as possible
Batch Rendering in LWJGL3 | Coding a 2D Game Engine in Java #11
44:04
How To Choose Mac N Cheese Date Night.. 🧀
00:58
Jojo Sim
Рет қаралды 84 МЛН
Happy birthday to you by Secret Vlog
00:12
Secret Vlog
Рет қаралды 6 МЛН
They Chose Kindness Over Abuse in Their Team #shorts
00:20
I migliori trucchetti di Fabiosa
Рет қаралды 12 МЛН
Каха и лужа  #непосредственнокаха
00:15
Game Camera OpenGL | Coding a 2D Game Engine in Java #7
23:48
GamesWithGabe
Рет қаралды 20 М.
GLSL Shaders | Coding a 2D Game Engine in Java #8
21:33
GamesWithGabe
Рет қаралды 14 М.
Texture Loading in LWJGL3 | Coding a 2D Game Engine in Java #9
27:36
The Tyrannical Mods of Stack Overflow
12:15
GamesWithGabe
Рет қаралды 375 М.
5 Signs of an Inexperienced Self-Taught Developer (and how to fix)
8:40
Why I removed Components from my Game Engine
13:07
Joshua Manton
Рет қаралды 42 М.
How To Choose Mac N Cheese Date Night.. 🧀
00:58
Jojo Sim
Рет қаралды 84 МЛН