RustConf 2018 - Closing Keynote - Using Rust For Game Development by Catherine West

Поделиться
HTML-код
  • Опубликовано: 27 авг 2024
  • RustConf 2018 - Closing Keynote by Catherine West
    When you’re just starting out in Rust, you start by building small programs. As we all know though, medium and large projects can have very different, unique kinds of problems that smaller projects never encounter. As our projects grow in size, we need to be increasingly concerned about code organization, separation of concerns, implementation hiding, and other techniques to manage growing complexity.
    Most languages have tools and patterns to deal with this, and Rust is no exception. However, the patterns that we learned from other languages, especially in mainstream OO languages, are often unhelpful when applied to Rust, and this can lead to a roadblock when trying to transition to building moderate or large Rust programs.
    This talk will cover a case study of a moderate sized game engine written in Rust and Lua, and show strategies for implementing things in Rust where common implementations in other mainstream languages are a poor fit. I’ll also discuss some examples of problems unique to Rust that ended up with very nice -but sometimes not obvious- solutions.
    Along the way, I’d also like to discuss working with Rust in game development generally, and what it’s like getting Rust to run on mainstream game consoles.
    Slides at kyren.github.i...
    The blog post mentioned in this talk is at kyren.github.i...

Комментарии • 91

  • @The9TKitsune
    @The9TKitsune 5 лет назад +195

    "And this a shared pointer to void-" RUclips app crashes. Couldn't be more perfectly timed.

    • @nexovec
      @nexovec 3 года назад +6

      hahaha that's priceless

  • @Condog64
    @Condog64 Год назад +28

    I feel bad because I originally came to this talk from Jonathan Blow's critique years ago. And I guess I'm really glad he did that video, because I love this talk. Ignoring the stage jitters that just goes with the territory, Catherine West is a fantastic speaker. I've watched this video maybe 3-4 times now.

  • @ErichDonGubler
    @ErichDonGubler 6 лет назад +147

    Hah, that was me right at the beginning saying "You'll do great!". Glad to see it made the cut! :)

  • @drbawb
    @drbawb 6 лет назад +89

    I've been hearing people reference this "great ECS keynote at rustconf" for a week or two now. Glad I finally get the opportunity to watch it! -- Nobody mentioned it was re: chucklefish/spellbound, and now I'm even more excited!

  • @godmodeon666
    @godmodeon666 2 года назад +6

    I am sad she said this might be the most uninteresting talk of the conference.
    She is an excellent speaker and I was eagerly listening the entire time. I usually skip like a madman thru talks and found myself 30 minutes in having not skipped at all.

  • @Huy-ed2re
    @Huy-ed2re 5 лет назад +9

    I like the way she warned the audience for things they might not like about her talk. That sounds even more sincere.

  • @TheBicPen
    @TheBicPen 11 месяцев назад +3

    I love this talk as just a talk about game design, not just as a Rust talk. I've been searching for good tutorials on designing a game for a while now, and most either use an existing engine, or use an extremely simple design.

  • @mani98
    @mani98 5 лет назад +17

    Experimenting with Rust myself and watched this talk before jumping in. Thanks a ton this saved me from hours of OOP work for sure!

  • @flwi
    @flwi 5 месяцев назад +1

    That's an excellent talk! So glad it popped up in my timeline. Will watch it again after reading through the article and experimenting a bit.

  • @zhou7yuan
    @zhou7yuan 3 года назад +8

    Question I Keep Being Asked [0:49]
    (code sample) An Answer: The Design of a Medium Sized Game Engine [1:43]
    Rust Makes Certain (BAD) Patterns more painful than others, which is a good thing! [2:49]
    The simplest possible Game Engine - Global Mutable Game State with "SYSTEMS" [4:57]
    What can we learn from this [6:10]
    downsides:
    everything global & public
    everything procedural & unchecked, systems have unlimited mutable access
    Too Much Object Oriented Design [7:55]
    (code sample) Making a game engine with OO design [9:21]
    (C++ sample) EntityIndex (no one use pointer)
    Using Classes & Interfaces [12:14]
    New Requirements Start Coming In [14:01]
    The more layers you have for re-use, the more accessors you need [15:59]
    How many accessors could you possibly need? [16:53]
    Let's Try this is Rust [19:11]
    -> Rust [19:37]
    (Entity, GameState)
    The larger the structure is, the more you borrow [22:13]
    Takeaways for game development and Rust Development in General [23:24]
    Back to the beginning [24:46]
    And the simple update loop structure with "systems" [25:05]
    Let's unify our Entity type [26:38]
    generalizing the fields on our entities [27:18]
    Takeaways for rust uses in general [29:37]
    Generational Indexes are awesome [31:18]
    better than Vec [32:27]
    Putting it all together [32:53]
    Takeaways for rust users in general [33:22]
    Dynamic Typing is nice in Controlled Quantities [34:09]
    Adding a component always has to change our game state [34:53]
    Let's use AnyMap to store our components [35:26]
    The "REGISTRY" PATTERN [36:22]
    We can add all of our individual "registries" to one big top-level "registry" [37:48]
    Takeaways for rust in general [38:40]
    Closing thoughts [40:00]

  • @PBrrtrn
    @PBrrtrn 3 года назад +3

    "forceNude()? What kind of game did I make?"
    This cracked me up really badly, had to stop the video for a minute. This presentation was awesome, not just because of the little stuff like that but also really loving the down-to-earth rationale for ECS and the problems OOP brings in the long run.

  • @Hoowwwww
    @Hoowwwww 6 лет назад +231

    First of all, thanks, you show OOP example, then say why it is bad, then you try to translate it into an other language, and show why it is bad, and then you show what are the alternatives, slowly you focus on the data, then you explain why ECS makes sense
    This is how people show treat the OOP issue, instead of just saying "LOL u idiot why u use OOP"..
    So Catherine West thanks a lot! i'll experiment with ECS a bit more, even if i don't use rust, i'll do it with my favorite language

    • @JP-mc3bv
      @JP-mc3bv 5 лет назад +11

      Yea it's always great when people take you through their reasoning and how they got to their conclusion instead of being derisive about it.

    • @nexovec
      @nexovec 3 года назад

      17:00 "private: // ..." :D :D :D :D

    • @Mautar55
      @Mautar55 3 года назад

      I know right? Now i can show the issue to my friends.

    • @tiagodagostini
      @tiagodagostini Год назад +1

      Well I would prefer if universities stopped teaching and PREACHING OOP. OOP is nice to teach basic programming, but it is horrible for system with complex relations.

  • @mindstreamx
    @mindstreamx 6 лет назад +9

    Now that was a clear explanation and made some very valid points about OO design.

  • @blenderpanzi
    @blenderpanzi 6 лет назад +27

    I'm not a game developer, but there is a certain small indi game with public source (not sure if FOSS license, but you can compile/port/whatever it yourself). It did the taking internal pointer thing to elements of a std::vector and then it sorted the vector. I actually experienced the resulting crash while playing, debugged it and submitted a patch to fix it. :)

    • @akj7
      @akj7 4 года назад +4

      Of course saving a pointer to elements of the vector is stupid: the internal array gets reallocated to increase its size, which places the elements of the vector at newer positions. It is even mentioned in the reference. Is C++ at fault?

    • @camthesaxman3387
      @camthesaxman3387 2 года назад +1

      If it was a linked list instead, then it's valid to store a pointer to one of its elements, since list items never move.

  • @sindisil
    @sindisil 6 лет назад +8

    Thank you so much doing this presentation! It's my favorite, by far, of the past year!

  • @RG001100
    @RG001100 5 лет назад +3

    I read the blogpost not the video.
    Wow, what a great post!

  • @phlimy
    @phlimy 4 года назад +4

    Thank you SO much, I'm so happy to have stumbled upon this.
    I've struggled for a long time to organize my game code cleanly, and this talk will help me a LOT.
    I love how we get to see the actual problems with OOP hands on. These are problemd that I stumbled upon and prevented me from going too far down the OO road but I wasn't sure if the problem was just with me.
    The transition over to ECS is perfect and feels very natural, and it's a great explanation of the design decisions.
    I'm super eager to get started playing with this! Again, THANK YOU!

  • @bradleat
    @bradleat 4 года назад +1

    i was waiting for 28:44 the entire time. i don’t program game engines, but it just seemed like the best idea to me

  • @sitton76
    @sitton76 Год назад

    Seen a good deal of rust video talks, and this one was really really informative.

  • @cvrptn
    @cvrptn 2 месяца назад +1

    I like the talk a lot, and it's made me reconsider the design for my own lightweight game engine written in Rust. However, I'm wondering whether the whole generational indexes approach is the best way to go. Either you have very sparse entities with lots of different component arrangements (in which case you'll be allocating a lot of memory in your EntityMap component stores for entities not using these components), or your entites all have sort of the same set of components (in which case you might wonder if it's not better to just have a single Entity struct that contains all your components and store it in a large Vec). Granted, the EntityMap pattern allows for very fast O(1) lookups of your components but it comes at the cost of wasted memory.

  • @timdiekmann5751
    @timdiekmann5751 6 лет назад +14

    Is your Blog post already uploaded? I'm really excited about it. Great talk!

  • @AlexHoratio
    @AlexHoratio 6 лет назад +89

    I watched the whole thing but I realize at this point that I have no intentions to make my own game engine and I don't know how to use Rust. ._.

    • @nonenothingnull
      @nonenothingnull 6 лет назад +14

      "...what you can learn from it, even if you're not a game developer"

    • @okdoomer620
      @okdoomer620 6 лет назад +16

      welcome to youtube

    • @CripplingDuality
      @CripplingDuality 5 лет назад +4

      Well, look at it this way: she is making a convincing argument that Rust's idioms and constructs make programmers more productive in building high quality, performant software. I haven't bought a game at launch in years because I find that it can take up to a year before the product is stable. Wouldn't it be nice to not have to delay that gratification? If we have good evidence that the tools that game devs use are inferior to some of the alternatives, and we speak their language, we can hopefully convince them to give those alternatives a try. :)

  • @scriptozavr
    @scriptozavr 6 лет назад +3

    Great talk Catherine, thank you!

  • @atarawhisky
    @atarawhisky 4 года назад +2

    Wow, I LOVED this talk!

  • @hatorizenzo8769
    @hatorizenzo8769 4 года назад +2

    Thanks for the video, I learned a lot today. Never heard of ECS before let alone consider it. I was trying to make a sandbox-ish program for a game I play, went ahead with OOP and it gets weird really fast in Rust.

  • @Vigilon
    @Vigilon 6 лет назад +12

    So... how do I implement the "monster damages player" functionality under this architecture? Where does the code live? Is it a method on one of the component traits? What arguments does it get? Does it need a mutable reference to the entire ECS?
    I'm a tiny bit disappointed because it seems like the talk ended without explaining how the proposed solution actually solves the problems that it brought up. Well, it does explain some of them but not all.

    • @peppeppeppepp
      @peppeppeppepp 6 лет назад +4

      You will learn that here: slide-rs.github.io/specs/
      But in short: You register functions to ECS that use some components as an input and modify some other components and these functions are called on every entity that has those components present. This way those functions can even run in parallel. So for example basic physics is implemented by function that takes position, motion and mass components and updating position component.

    • @Abubalay
      @Abubalay 6 лет назад +9

      You write it as (part of) a System- so yes, it gets a mutable reference to the entire ECS, but that's fine because it runs as its own phase of the game loop. Instead of zooming in on one interaction ("monster damages player") you zoom out and handle things holistically, detached from any individual piece of that interaction (e.g. maybe "player/damager interaction"). That way as these interactions get more and more intricate, all of that complexity stays together in one place rather than spreading out across the entire codebase.

    • @anotherelvis
      @anotherelvis 6 лет назад +2

      This code is often saved in procedures named Systems (the S in ECS). One solution is to have write procedures such as update_all_positions that iterate over all entities. If you give each procedure mutable access to he entire game state, then you can introduce a trait named System and implement it for each of the procedures. This allows you to iterate over systems/procedures to update the entire game state.
      If you want better of scalability, then you can introduce message passing (event sourcing).The idea is that update_all_position works on an immutable ECS, and it generates a list of events to update the state. These events are processed afterwards. I tried this and it was fun to write, but in hindsight I don't think that it was worth the trouble.
      EDIT: But you get much of this for free by using specs

  • @samphire
    @samphire 5 лет назад +6

    Please use the mouse pointer to point next time you present, we can't see your laser pointer so its really hard to follow what you're talking about. Also, camera person, please stop moving the camera, frame the shot and leave it alone. Thanks!

  • @veetaha
    @veetaha 4 года назад

    Awesome talk, did learn a lot from it, thank you very much!

  • @TadejKanizar
    @TadejKanizar 6 лет назад +1

    Really great talk

  • @IgneousGorilla
    @IgneousGorilla 2 года назад

    What an amazing talk fr

  • @TheLavaBlock
    @TheLavaBlock 5 лет назад +1

    Interesting and great talk. Thanks

  • @MathieuTanguay2802
    @MathieuTanguay2802 6 лет назад +3

    I would really like to have a link to the blog post when it is published. Very interesting talk.

    • @Auroden
      @Auroden 6 лет назад

      Maybe you already saw it but:
      kyren.github.io/2018/09/14/rustconf-talk.html

  • @adamblance3346
    @adamblance3346 2 года назад

    This was super informative, thanks!

  • @monomere
    @monomere 3 года назад

    Amazing talk!

  • @tathanhdinh
    @tathanhdinh 6 лет назад +5

    19:11 => Let's try this in Rust

  • @tommmlas
    @tommmlas 4 года назад +2

    Great presentation. Had to revise written version multiple times & managed to implement base version, but still have some questions.
    So at some point we have all structs to store our "players" entities and different type of components. But how do we relate those?
    I mean for player entities for sure we'll allocate generation index with alocator. But what about components? Do we expect to set components by entity index to retrieve it back while just having entity id. Or maybe allocate new indexes for every component as well? In case of latter, how do we query components by entity id?

  • @NickDrian
    @NickDrian 6 месяцев назад

    great talk!

  • @darkexior
    @darkexior 2 года назад

    Thank you

  • @Neightr0
    @Neightr0 5 лет назад +2

    Does anyone know what the official name for the registry pattern is? I'm curious to read more about it, and I'm trying to find a name for it. I think the pattern would have a lot of potential for creating plugin interfaces. Maybe you could just have every plugin contain some sort of metadata, and then when you load the plugin you read it and load the specified types?

  • @renney77
    @renney77 6 лет назад +1

    I'm unsure about two parts here.
    1. At 29:00 ish change from an array of structs to a struct of arrays. I don't think I came across this before, what is the advantage in certain context for that? If it's conventional, any links to good resource on that?
    2. At 35:30 ish Catherine is talking about using this AnyMap because you don't have to list all the arrays of EntityMap. But don't you have to add them all into the AnyMap at some point anyway??
    Great talk!!

    • @etodemerzel2627
      @etodemerzel2627 5 лет назад +1

      1. en.wikipedia.org/wiki/AOS_and_SOA and google some other resources

    • @Wren6991
      @Wren6991 5 лет назад +8

      Struct of arrays gives better locality of reference. When you're doing your physics calculations, you'll get better performance if your top level cache is filled with physics data rather than, let's say, 20% physics data and 80% unrelated stuff that happens to be in the same object.

  • @MikeMike-bd8vw
    @MikeMike-bd8vw 4 года назад

    That was great. Thanks.

  • @lordofwizard835
    @lordofwizard835 2 года назад

    She is soo awesome

  • @espadrine
    @espadrine 4 года назад +1

    The Vec would grow unbounded, though right?
    I assume that is the point of the generational index, but wouldn’t a HashMap be better than the Vec?
    You wouldn’t need the Option, too.

    • @tech6hutch
      @tech6hutch 3 года назад +1

      I don't think a `HashMap` would work because you'd have no way (at least no `O(1)` way) to get an entity by its index. The point of generational indexes is that they overlap on the index part.
      Maybe you could use a `HashMap`? But then storage wouldn't be contiguous in memory, which is the advantage of using a `Vec`.

    • @lflime
      @lflime 3 года назад +1

      @@tech6hutch A HashMap get is by design O(1), if you have the hash of your enity (which you have most of the time). Plus youd get a add and delete of O(1) also. I build an ECS based on dictionaries in C# and it worked like a charm and was fast. BUT. If you have Systems that need to iterate over the full collection (like physics) a Vec or a List is faster and easier. Like always the anwer is "it depends" on what you need in your game.

    • @nazarkostetskiy4822
      @nazarkostetskiy4822 2 года назад

      I'm not from Rust, but I'm also wondering why they are using Vec and making abstraction on it and then naming this abstraction EntityMap. Why just not use HashMap for this and get entities by key? We don't need any indexes and etc

    • @yokunjon
      @yokunjon 10 месяцев назад

      Vector has better data locality. It is mostly about iterating. When you apply physics results into transforms for example, there could be lots of updates for majority of the entities each frame. So, iterating them in predictable arrangement of physics stats and transform order plays to the cpu cache.

  • @shreevari
    @shreevari 3 года назад

    This was fun

  • @AxWarhawk
    @AxWarhawk 6 лет назад +1

    Blog post is up: kyren.github.io/2018/09/14/rustconf-talk.html

  • @User-cv4ee
    @User-cv4ee Год назад

    With generational indices, how do you know if an object has indices stored to it in some container and if it is safe to delete it? I could store players in all_players and again same indices in team_1, team_2 etc. An `Rc` would prevent this?

    • @Architector_4
      @Architector_4 3 месяца назад

      When you're retrieving an entity (i.e. its components) with an index, you get back an Option (or multiple) from the storage. This explicitly requires you to check if that Option actually has a component in it or not. You are free to delete the entities entirely at any time; later on, when checking an index of a deleted entity, you just get the "None" results. At that point you're free to just skip to the next index, if any, or clear it from your index map lol

  • @loganhodgson6343
    @loganhodgson6343 2 года назад

    In rust, how do you access different fields of the AnyMap at the same time? Each get_mut call blocks you from accessing other fields mutably.

  • @mzg147
    @mzg147 Год назад

    What is the difference between arena allocator and "vecs with indexes"?

  • @jsonft5417
    @jsonft5417 5 лет назад +1

    Just... thanks!

  • @neoplumes
    @neoplumes 3 года назад

    Does anyone know if there's a crate out with this ecs?

  • @aprettz
    @aprettz 6 лет назад +4

    Great talk!
    By the way the video title here should be changed to something more informative than "Closing Keynote"

    • @RustVideos
      @RustVideos  6 лет назад +3

      Fixed! Also added a link to her slides.

  • @tvanantwerp
    @tvanantwerp 6 лет назад +8

    New ambition: play Starbound for as many hours as there are lines of bad OO code in the player class source code.

    • @stevesan
      @stevesan 6 лет назад +4

      can you explain to me why those lines of code are bad? aside from "omg that's a lot of boilerplate"?

    • @naxaes7889
      @naxaes7889 4 года назад

      @@stevesan The player class has too many responsibilities and is not very dynamic. Given enough time, it's likely to become a "God class" as well.

  • @codmw2FrEaKk
    @codmw2FrEaKk 6 лет назад

    Is the Blog Post already out? I can't find it...

  • @stevesan
    @stevesan 6 лет назад +2

    alright alright, can someone explain to me what's so bad about that C++ player class with all those accessors? yes, it's a lot of accessors...but all those are things that one might want to read/write about the player..i don't see the problem. is it just the volume of boilerplate?

    • @Mathspy
      @Mathspy 5 лет назад +9

      If you're making an OOP system and all those "private" by default things are just private behind accessors you ought to realise "There has gotta be something I am doing wrong" because then the pattern just exists for no reason.

    • @skaruts
      @skaruts 5 лет назад +3

      Well another thing I noticed is that it seems to know more stuff than just about how to be a player and behave like one. The scope of the class went beyond what was probably originally intended. That may or may not be a bad thing, but it certainly breaks the principle of single responsibility, and that one turned out a bit messy and bloated.
      I think it's been one of the major problems of OOP is that it's really hard to actually follow its principles. Currently trying to wrap my head around other paradigms because of that. OOP is great for some things, though, like UIs.

    • @charonstyxferryman
      @charonstyxferryman 5 лет назад +6

      Breaking encapsulation.
      If private fields actually, via getters and setters, are public - just create a strut with public fields and borrow it out to anyone who is interested in using its data.

  • @kim15742
    @kim15742 4 года назад

    Heh, this is funny, because I wanted to give up rust with the exact though "I nedd RefCell" everywhere

  • @jonathanmoore5619
    @jonathanmoore5619 3 года назад

    In the beginning there was ....

  • @maverickreal09
    @maverickreal09 2 года назад

    If rust is not the future then the future is rusty.

  • @sergesolkatt
    @sergesolkatt 2 года назад

    HARDCORE

  • @deanroddey2881
    @deanroddey2881 4 года назад

    It has to be said that there's a lot of anti-OOP in here, but that's not because OOP is bad, it's a very powerful tool. You just need to use it where it's applicable. Too many people these days take these types of talks as proof that OOP is inherently bad and should always be avoid, which is just silly. Everything is inherently bad if it's the wrong tool for the job. If there are natural hierarchies involved, and very often there are, OOP is a perfect tool for the job.