Subliminal
arrow_backBack to results

Star Citizen Live Gamedev: Building NPC Behaviors

28 May 202101:09:452,006 linesWatch on YouTube ↗

Transcript — every row opens the video at that moment

  1. 00:00:03

    Hi everybody. Welcome to another edition of Star Citizen Live Game Dev building NPC behaviors. I'm your host Jared Huckaby. And if you've never seen Star Citizen Live before, it's where we take about an hour out of the end of our week. Uh hang out with some of our esteemed Cloud Imperium Games developers. Uh either answer some questions, do a little back and forth. Sometimes we take a look at what they are working on. Today, we are doing something that we've never done in the seven years I've been doing this for for CIG. We are going to look at the actual process of creating NPC behaviors. And to do that we are going to let's first uh introduce ourselves to some of our AI team folks. Uh Fran, b- uh because you've been on the show before, we'll start with you.

  2. 00:00:51

    Uh who are you and what do you do for Star Citizen? Sounds good. So, uh hi everybody. My name is Francesco Roccucci. And I'm the AI director in Cloud Imperium Games. So, yeah. Well, I try to supervise all the AI development and you know help everybody with the with the proper planning, you know, the proper development of architecture. And yeah, support everybody in the behavior you know, creation as well. Let me see that shirt you're wearing. What? Sorry? So, this is a very nice version of the Space Invader game. See? With Pinchanzo, this is a tardi- How how do you pronounce it, Jared? tardi- in English? tardigrade tar- tardigrade tardigrade? tar- Exactly. I can never pronounce it

  3. 00:01:39

    correctly in the in English. In Italian it would be tar- tardigrado. All right. Uh we'll go we'll go clockwise around. Uh Dan, who are you and what do you do for Star Citizen? Hey, I'm Dan Baker. I've uh been working at CIG for about four years now. I'm I'm one of the game designers here. Uh currently working on the NPC behaviors as um you know this this whole stream is about and working on usable and I spend most of my time writing design documents and playing around with data. Exciting. Jacob The man with the blurred background, what are you trying to hide? Oh, you don't want to know. You don't want to know. Who are you and what do you do for Star Citizen? I'm Jacob. I'm a junior AI programmer and I joined here about 3 months ago. So it's it's my first like full-time

  4. 00:02:27

    job. It's my first job in the games development sort of sector and I basically I work on behaviors as well like AI behavior but also like sort of the you know the backbone of it like the implementation and the code and stuff like that. So excited to be here. What we what you right now see already live with the with the pilot security behaviors what Jacob has worked on already. Yeah, exactly. So if you have any complaints, you know, should complain. Not being a pilot. And last but certainly not least Hayden, Oh, I'm Hayden Muckle Roy. I'm a junior technical designer and I basically do what Dan does just with a little less documentation. Just a little less. The higher up you go, the more documentation you have to do. Lucky you.

  5. 00:03:15

    And let's go ahead and mention Idris. Idris was going to join us today but he's having some trouble joining on Zoom. So Idris, you're with us in spirit. All right. So Fran, this is this is your program. We're all here to peanut gallery and and just tell you where you're messing up and what you're doing wrong while you're working. No pressure, no pressure. Why don't you why don't you start us off? What is an NPC behavior and and what are you doing? Sure. Basically I think like all of last year we both on you know some of last year again as programmer I work on some of the systems, we we we define, we design, and we build and implement. Some others, you know, as the designers are mostly working with the systems we build and they, you know, help us building. So the behaviors are

  6. 00:04:03

    mostly it's mostly the brain of the NPCs, right? So the way we split the things is we try to build, first of all, as much as possible needs to be data driven to scale up, right? In this game it's it's so huge we need to just, you know, allow the designers and content creator to create content that we use automatically, right? To patch the game and expand the game. And one of the things we want to show today is something that me and Dan have been working on, you know, since a while and I think we also shows a sneak peek during the mostly during the monthly reports, but this is the is the engineer behavior as an example of how we build a behavior from basically scratch, right? So how we define mostly what we want an activity to do because we talk about behaviors in terms of activities usually. Activity is kind of a generic um

  7. 00:04:52

    kind of a representation of a job, right? It could be the engineering job, it could be the pilot security that Jacob has worked on or the tourist that Aiden has been working on. Something that the NPC can do and that, you know, eventually I'm sure like a lot of people that are watching here they saw the Tony's Tony's video and all that was was out this week and you know, all these things with the population manager. Oh, Idris China's. Um but they say all these really cool population manager, you know, and the visual NPC and something like this we can basically spawn them in the right context and their context is the activity what they are they're trying to do and the environment which they are in. So yeah, basically that is what an behavior is and to achieve that, you know, let's say an engineer, you have a lot of pieces that, you know, we have to take care of that is like building

  8. 00:05:40

    environment or making sure that the NPCs understand the environment as well and, you know, and then there is the actual decision logic decision flow. And what that means is that we try to abstract our like thought process flow. It's like, oh, I want to find something that is broken. I want to repair something that is broken. And then how that basically construct the actual action that they need to perform. It tries to be as generic as possible, as modular as possible. And this is what we will see today. All right. Well, that sounds like something relatively easy, straightforward, and Yeah. should have no trouble doing it within an hour. Yeah. So, I've tried I've tried my best to be fast and not, you know, because I'm I'm I'm I as a lot of people know, I talk a lot. So,

  9. 00:06:28

    you guys need to try to interrupt me sometimes if I just speak too much. Yeah, I think we're going to try and squeeze like months and months worth of work into an hour, so Yes. So, we are trying to focus on specific stuff. We'll see how much time we have. Of course, we can go more in detail. Maybe we Jared, you know, you can book us for another session after this, you know, we can go more in detail later. Hey, I got to do this every Friday, so good. All right. So, we've got your screen share up on the up on the stream now. What what where do we start? So, we start with this is our engine, right? So, this is I think, you know, you know, I've been seen in the past, but basically this is an empty level, just like completely empty. This is what we use for testing, for development, and for actually trying and testing the program environment. So, what we'll do today, of course, is building a test environment. First of all, we need a

  10. 00:07:15

    platform where to be because right now if we jump in game, we're just floating in space and there is just pretty much nothing uh you know, we we can do. So, we will use what we call designer's tool that is like a kind of solid creation tool. We can create like a platform uh and the way you know, we move around. We can build like uh different type of uh surfaces. Now, we have an environment where we can place NPC. Now, we are still in zero G, so if I still jump in game, I will still float So, first thing I want to do is add some gravity. I will go in the entity panel. I will search for what we call the gravity box. We drag it in. As you see here, there are like these little, you know, this little square is where now gravity is. So, if I go next to here, you know, and I will jump in the game,

  11. 00:08:03

    I'm here. Cool. So, I'm perfectly in the level. I can walk around. Let's take an NPC. As the company, you know, is is very complex in the process that we have to create from the character to the behavior. So, let's say usually what we start is that let's say we want to do an engineer in the in the parallel process, we have the character team that creates, you know, the character like as I the human body and then all the loadouts that the engineer comes comes with. So, in this case, we can just grab like one of the engineering uh in uh New Babbage, I don't know, or something like this. They are female and male, of course. Uh we can start with, you know, being a female, but I think I will show you basically that we are in the process of testing. Uh always like basically we start with some animation this male or

  12. 00:08:50

    female and then we transport that animations to the other type of skeleton rig. So, some might be, you know, uh depending on the on the time in which we are working on, they might be more or less polished because of course we want to polish one first and then uh do the retarget retargeting. So, first of all, now we have this this character. And that's what I wanted to show you is basically in each character or each entity in general, it depends on entity type, we can configure some instance properties. And some are are behavior related, right? So, the one that we can show you here is that this is like is now a sign a behavior that is called PU engineer or better an activity that is called PU engineering. This is the old activity that we have sometimes in PU where you see some of the engineer going around, you know, and use like

  13. 00:09:37

    some work zone and you know, weld stuff and and and sundry this. But now we are working on a more complex one and we will definitely start with with known with a new one. We would just create one from scratch. So to create one from scratch, we will go into sub function. This is our tool for creating behavior, missions, you know, populate environment where we hold the object containers where we can create platforms. We can define which type of actions the designers have exposed from the coders, which type of variable they can use and so on and so on. But let's start with one. I pick my my folder. I show I make a new behavior. I call it engineer. I show. This is going to be the name that we can reference

  14. 00:10:24

    to the inside the engine. And we can assign it to here. And in general, like everything we do here gets live hot reloaded. So if right now for example, we take a sub activity, we go we go with a generic one that is like if nothing happens, if he has nothing to do, it just goes into idle. We put priorities. This is like the number in which we evaluate those the sub activities. So what are sub activities of course? Sub activities are a sort of the way we split the activity into the different things they can do. So let's say we have an engineer. Maybe you have like again an idle sub activity that represents your fallback. So like okay, there's nothing to do, you're just going to be there. This pretty much will never happen. So we'll put it like in a very high or very low

  15. 00:11:11

    priority that is a very high number. And what we usually tend to do as a first step, we just put like these are all the nodes, all the things that we can put in the logic. Let's put we call one that is called halt. Halt is pretty much doing nothing. It just stays there. The behavior runs and it's going to be there forever. So what we're I'm going to test if this is already working. We jump in the game. We have this character here. We jump in the game. What we can do, we can look at a character because this is going to be a very easy thing to debug. And we press on our keyboards, we have like the slash on the numpad. And basically what we can see is like there will be on screen some information about the behavior. Here you can see of course like this the the the log, but on top you can see the name of the activity that is engineering action, the one that

  16. 00:11:57

    we just created. And the primary name that is uh staying in idle. This is no special variable. There is something on the bottom. They can see that it continues to run. That is like how many seconds the sub-activity has run or the sub-activity has started. So, now we have a really basic things that kind of works. Of course, it doesn't do anything. Um so, what we want to do is right now we want to verify if this character can move around because if you can't move is definitely not going to be able to interact with anything. What we usually do is that we have this AI physics button that will allow us to move in the environment, but also to interact with the object. So, right now the behavior is running. And we have like a middle click button that if we press around, the character should move. What we see is like eh, it's not really moving. So, what's going on? We didn't put navigation mesh. So,

  17. 00:12:47

    what's the navigation mesh? It's the representation of the environment to for the AI behavior to be able to move around. How we do that is we we create a volume pretty much around the environment. We can decide if we want to snap uh to the ground, to a grid. Just right now just put it that we want to keep it on the solid. Uh we just create like uh a square around the character. We can move it a bit down. We can sink it a little bit more. We save. So, it's good uh practice save all the time because you know, never know if crashes eventually. And we can go back like draw like this one here. As you can see, there's this blue uh like uh square. Uh we can see how it's how it's implemented a bit more uh Sorry, I just take a bit out of my screen.

  18. 00:13:34

    So, if we see this is our um console, we can see like uh C vars uh that are like a way for us to control the environment. And the background, we can put like three. It's usually showing us what how this is represented internally, that is like tiles and triangles. So, they are usually when he moves around to the environment, he creates like a path that is just a transitioning through those triangles or through those tiles. If we middle click, now it will run. With shift middle click, we can make the the walk movement and we can test how the locomotion works. With alt, we can just make it sprinting. And we can just like very easily test, you know, if the movement is is working as we expect. Cool. So, we have like just the basics. What do you think, Jared? All clear so

  19. 00:14:23

    far? I think we're halfway to our start to this RTS. Exactly. Exactly. for new starters. We could. We could. It's actually uh I was thinking the same when I was preparing it. So, I think like Oh, you have no idea. One of the how many how often I get messaged from new employees who are just starting and like, "Hey Jared, I just want to say hi. I've like I learned about the project from watching your videos and I like I decided you were the place I wanted to work at because of the video." So, yeah. It It is It is helpful to show these tools, right? Because I think sometimes we also like so much deep into development that you know, we should just sometimes spend a little bit more time to record those things even internally. That that would help a lot. Um but it's good to use these things. At least it gets you know, a bit more broader view and

  20. 00:15:12

    it's always good. So, now we want to have something to do for this engineer and a way to have something to do is of course defining, you know, what they should do. That is the designer in charge and maybe you can tell us something about what you would like him to do. Or what usually an engineer does for us. I usually would I guess he would go to something and fix it. Yes, exactly. So, this is exactly what, you know, what we what we do that then basically design it in a way in which basically the engineer supposed to, of course, in our game to get tasks to do and this usually repair stuff, right? This is what we want them to do. So, one thing that Yeah, sorry for I was just going to say like the the key corners we we tend to try and find like a key cornerstone of every single behavior. Like what what is

  21. 00:16:00

    the purpose for having this behavior? Because otherwise, you know, there's there's nothing really unique about them and they could just still be running the same behaviors. So, so with the engineer it's more about well, they they can do everything like everybody else like they're, you know, getting changed into whatever the relevant clothes are or, you know, finding somewhere to sleep if they need a rest or things like that. But but for the engineer it's all about maintaining things. You know, they their their job is literally to um inspect things to see if they're broken, repair things if they can be It's It's an archetype. Yeah, I guess. Exactly. the word? Yeah, we basically use like yeah, like um I we call it active this, but yes, it is it is a sort of an archetype of, you know, a job to do. And in essence, I think what is good is that they actually

  22. 00:16:49

    I think compared to lots of games where I think we like yeah, usually tends do stuff, but it's not really having an impact on anything, right? What we are trying to build is something that, you know, whatever action they do actually has an impact in the game. So, what we want to show today is like, you know, imagine we have a wall panel that is split between two different sub elements that we call relay. And this relay can have sub components inside that are probably like in our test are fuses. These fuses can actually have gameplay impact, right? And they can break for different reasons. Then you as a player can go there and replace it. If the AI does it, has the same exact effect as, you know, what the player would do. So, for example, if you hire this guy and you want him to be your engineer on board of your ship, you can then give him command and say like, you know what, maintain all the wall panels in my ship.

  23. 00:17:38

    Or, you know what, I see in my, you know, map that this wall panel is broken. Can you repair it exactly this one? And this is how we are building these behaviors, that they are sort of API of interface where you can control them. It does In essence, it's like designer writing a mission are kind of doing the same as a player would do when they, you know, give commands to an NPC. So, right now what I prepared, just to speed up a little bit, of course, I prepared some pre-configuring in case we don't have some time. But the idea is like I have some default object. Let's say, you know, art creates for us some objects that we can use as a reference. In our case, we have three objects, that is the wall panel, the actual sub component like that you will be the fuse and the relay. So, we'll show you all of those right now. Um And also, just just um for anybody else

  24. 00:18:26

    that's watching, that relay could be any kind of ship component. It could be a quantum drive, it could be a shield generator. The idea is that, you know, this the wall panel is supposed to house any of those type of components and it could be in any environment. The engineer is is more of a infrastructure um maintenance person versus Exactly. mechanic that is more like, you know, small ship maintenance. So, this one basically Yeah, yeah, absolutely. And this is like, you know, one of the example we used today and, you know, the the relay, for example, right now is going to be done something like this. Sorry. Entities. Just prepare something we show us at least I can find them very quickly. You know, we have something like this. And as you see it's like it's a little box,

  25. 00:19:14

    you know, where with some uh movable parts and inside you can find some trigger component attached. How we do this one? Probably art already can deliver us like something with the default load outs where, you know, we can in our for example in this case this is the wall panel. We attach We have two Let me put the wall panel as well as these people can have like a visual reference to that. Basically uh the wall panel template. You see you have like two relays attached to to a panel. And then inside each relay you have three uh subcomponents. And what we want of course is like we don't want to hard code any information like about repairing a specific wall panel type with three, you know, two relay and then three specific um

  26. 00:20:04

    fuses. We want these to come from the setup of the object. And this is what we will build today. So what we'll create right now is Those are not usable yet. are just piece of art. Uh we want to make sure these objects become usable basically. So the first thing we will start with is uh I would say we start with the fuse because it's a bit the simplest one. So So you can see we can select things, delete. And now we will go in data forge and we will open the the fuse. We will create a variant that we will configure. Go to template show usable. We'll make a new version. We add right now the usable component. What's the usable component? I think we speak about

  27. 00:20:52

    this lots of the times, you know, about what the usables are. In essence a usable is the knowledge that the AI has about how to interact with that object, right? So in our case right now, we have a a fuse and we want to this an object you can carry. So, the way right now simply a simplified way, we want to just generalize this as an archetype is that it's a carriable object, right? So, we can take this one. We can just select this is a carriable object. Then, what we do is we want to create what we call alignment slot. The alignment slot is the position in which you need to be to interact with that object. Now, right now, we are not going to care about

  28. 00:21:40

    interacting with this object by itself. We will interact with this object through other objects that is the wall panel. So, in this case, we will just create like a generic alignment slot we call main and we will reference this one as the root. The root is really the entity position, basically. And if we go in here and we drag this new object that we just created, show usable. And now, for example, we debug draw usable {dot} debug draw. Of course, nothing goes there because we need to also enable the debug draw for carriable object because otherwise there's just a a lot of information

  29. 00:22:28

    here. And now, you will see there is no alignment slot because the alignment slot alone doesn't doesn't doesn't do basically any information. It's not you can if there's nothing to interact with, then there's no point of even showing information. So, what we'll do right now is also adding what we call use slot. The use slot represent sort of a virtual position in space or, you know, again, if it's virtual, it's virtual, but it could be a physical position where the interaction actually works. In our case, it's basically the center of the object, so you can interact from a position in that object, but no more other like no other people can interact with that at the same time. So, there is no way to have two people positioning at the same time around this object to to interact. So, you don't have multiple NPCs all trying to fight for having at the same time.

  30. 00:23:15

    That as well, exactly, right? So, we will make like a usable this called main and we will instantiate which type of use channel we can use on those object. And right now, what the the things that we care, I think we like we won't even have time to show them both, but let's say we can take this object and repair this object, right? So, if we search here for take, we see that we have different type of archetypes of the usable and different action. What we want to use is the carriable take in this case and we assign the alignment slot from which you can take it. And then we make another one. And we basically do repair. And then we make this one. Save. Go back to the to the level. Delete. We just put it back and now you

  31. 00:24:05

    see you have the back throw happening, right? Now, one thing that we want to extend, of course, that we don't have it yet is that these type of objects that they are carriable, they should have their alignment slot depending on their position of the object, but not on the orientation, right? Because if the orientation is irrelevant if these things fall, you might still need to pick it up from whatever position. And this is what we will extend in the next uh quarters. Uh but right now, let's say we are not planning to interact directly, so it it's it's a bit irrelevant. Cool. Let's go now to the relay, right? So, we take the relay and we do a similar things. Create a new variant. We make a usable component, we assign it. So, this is for was not super familiar even

  32. 00:24:54

    though with components is mostly there is this dichotomy in uh in programming that is about uh you know, inheritance and and and composition approach, right? So, usually most of the things, you know, are inheriting as a functionality from something else. Like, you might have like a vehicle, and then from a vehicle you inherit, then you create a car or, you know, But then what happens is that the things are in a way simpler, but a bit more monolithic. What we try to do here is like we try to get this responsibility on the component so you can build it out of the composition of of this functionality together. So, in this case, the relay, this could be multiple things as archetypes. The way we tend to do is I we try to use what we have, if we do have something that kind of fits, and then if things change, we might need to create a new archetypes.

  33. 00:25:41

    In this case, very much like we we we we can imagine that we can still carry this relay. It's going to be heavy, but you know, some people might be able to carry maybe with like, you know, an armor suit or whatever, then attach it to multiple, you know, things. So, it can still be a carryable. It might still just be uh I don't know, a container type, but we you know, right now we use a a carryable. Just for simplicity. And we do something similar uh in this case. We make the carryable, we create alignment slot. Since we are not planning right now to interact with this immediately, it it is a little bit irrelevant about this one. It's mostly this information is required by the system to be able to understand how those things are attached and how they flow into one one another. So, this is why it's it's important. And uh yeah, we will make the use slots

  34. 00:26:30

    as well in this case. Uh we would call it tank. Uh sorry. This would be still a main use slot. And then we'll have a tank from the carryable. We'll assign it to the right alignment slot. These hierarchies are I mean, you You understate how important they are to making all of this actually function. Yeah. How often is a hierarchy, you know, broken because you you have to create 20 different links in order to make these things and one of the 20 links is broken and the whole thing doesn't work. Yes, and the problem is often and I'm sure like, you know, Dan or I don't know, Idris can can say more is like it's so easy to even like get lost

  35. 00:27:17

    sometimes on why things don't work and I think we have constantly try to say like, okay, okay, this is like this is the problem. So let's try to add some extra the back draw to try to track it easier next time, you know, and we try to do that or like oh, this is like the the message is not really clear, right? And it's like we have to do this. the most simple thing ever. It could just be you're missing a left tag, you're missing a right tag and then you'd spend half a day debugging it and you're like, oh, it was just that and you missed this one little field. But yeah, there's a lot of information going into these usable. You you can spend quite a bit of time just breaking a single entity down to its core parts just seeing, okay, well, this is okay. So you take that out and then you put a different thing in and that's it's a bit like if you're building a PC and you just swap out different components just to see which one's the broken bit.

  36. 00:28:05

    Yes, absolutely. That that is usually a very good um like, you know, easy way for debugging stuff. Like you start to remove and it's like, is this one that broke? Or like just do a little step at the time. This is what I tried to add here is like this eye parts the back draw just to show you guys like that we have like these eye objects are attached to some item parts, right? The way we we define those are for example, if we go in here we do have this item part container for the relay and we can see that we have three slots that we call slots sub item one, slots sub item two, slots sub item three. We can attach stuff in. Now, we just need to explain to the usable code basically how this information is is available to it. And you have this

  37. 00:28:54

    usable item part, so we can create like one data here that says on the slot sub item one we basically can play specific animation when we interact with that, right? So, what we want to have is like eventually as a final result is that the engineer can go to the wall panel and understand this is interacting with the fuse that is on the top or the bottom. And then based on where that object is, it needs to play the right animation to take the the left, the center, or the right. So, maybe we should just explain a little bit more what how we play these animations, right? It's It's goes like It's like Russian doll thing like you start What is it? Oh, but there is still another piece that we need to explain. And here's like mannequin.

  38. 00:29:41

    So, uh why we could quite easily spend half a day talking about mannequin. Absolutely. Absolutely. It's It says a minefield. It's It's It's crazy like I think yeah, there's a lot of stuff, but basically in short, what it is is a lot of a game engine have what's called an animation graph, right? The animation graph will basically explain how animation state transition from one to another and which type of animation you need to play. And then maybe usually in these animation states, you can maybe say like, you know, with specific conditions which animation it gets played or how you can randomize through animations or something like this. Mannequin is a kind of a piece of the puzzle, so it's a sort of database where you can use what we call fragment ID and fragment tags to immediately search for a specific animation that match specific

  39. 00:30:30

    condition. The tags are sort of conditions, so you can say like, are you an AI or a player or which type of action are you trying to do? And in our case let's say let's go straight like in some examples. So, let's say we have like what we call fragmented D that could be usable usable action usable face usable title. The usable action is the action you can perform when you're in a usable. So, we call it usable action is just very easy to search. And then for example, you have all those folders. Those folders are in essence the fragment tags. So, it's a sorting when you go in a database and you search for some keys. This is what what you get and this is the animation results. In our case, we want to understand which animation we need to pick up specific object. In our case is the wall panel or the relay as three item parts. So, how can we define that? Did the animator and

  40. 00:31:19

    tech animation team give us already something that we can use. So, if we go here, we say, "Oh, this is the action we want to do that is the take." So, inside take do we have some version for the wall panel? Oh, yeah, we do. And then we have two versions. It's like high and low. And then we can create like we can we can take a look at those. And we have like, "Oh, we have a version for center part, left part, and right part." And it's the same for the bottom, right? So, this is what it means is one once we want to search for an action that is the action take for a wall panel on the high relay for the fuse that is in the center part 01. This is the animation we will play, right? And then in the animation, we can also specify specific procedural clip layer that is a sort of you know premiere layers but just like that some play some animation and some play some

  41. 00:32:06

    code. And here it says when you hit this key, then that item attaches it from the the relay. Now, it passes in your hand and it attaches from the other one. And as you see, we have different animations for you know the the left, you know, and animators can make multiple variation, multiple type of, you know, urgency on doing actions as well. So, we can basically pass this information from the behavior and the and then manage it takes care for us to select the right animation. So, those are the three that we want to do. So, it's like center port center underscore port underscore 01, left underscore port underscore 01, right underscore port underscore 01. So, now we go in here. So, just just in a nutshell, just so that it's super clear as well what's happening. Essentially, what we're doing

  42. 00:32:55

    is we're just putting these different a bunch of different tags onto the the character and then they just play whatever animation is associated with all of those tags. So, they say, "Okay, got all these different things. That's to this animation. So, I'm going to play that." And then in that animation, we can also have like little scripts to say, "Well, at this point in the animation, you want to trigger this interaction." So, and then that could be like, "Oh, I'm going to open the door at this point." You know, so, just trying to simplify it a bit more. Yep. Um, there's more here, but we will not see it today, but it's basically a way also to say from the behavior here, it would be like, "Oh, if I have something attached to this item port, this is the mannequin tag I get." But, we can also use this data to say, "Do you have something attached that respect specific tags?" And then basically, we can sort it out. Let's say you we say, "I want to repair this

  43. 00:33:42

    specific fuse." Then we can say like, "Okay, where is that attached and which animation I need to play?" But, we could also say, "Hey, usable, do you have something that is damaged and is a sub component attached to you?" And then it would be like, "Yeah, I have three, right?" And they say, "Just get this one." And this one is the one attached to the item port one. And to use this one, you need to take the left port 01 mannequin uh tag. This propagates automatically to the behavior later, we will see. So, you're giving it a collection of choices, not every single choice that's available for every single NPC, cuz that would be horribly unperformative. But, you're you're basically giving it its own little buffet of actions and based on the situation that it uh determines uh based on all the tags and what's happening, whether

  44. 00:34:28

    something's damaged, whether something's not, and whatnot, it it actually goes, "Oh, this thing is damaged. Oh, it's in the left port, so I'm going to use left hand. Dead animation. Exactly. And basically the good thing is that this comes automatically from what you already have calculated from the eye, so you don't really have like you can retrieve this data, but this data can be cached very easily from our code because once you touch the object there, then you can immediately say like, "Oh, it's a touch. Okay, cool. Is there some data related to this item or where I touched?" That one is like, "Okay, in the moment you attach it, this is when you calculate it." That means that, you know, attachment don't happen so often. While, you know, search happens a lot. If you do it every time you search, then it can be very expensive, but if you do it when, you know, you do the the bare minimum operation, this is where it can be much more optimal. Cool. So, we have this one right now.

  45. 00:35:15

    Seems kind of good, and we can now make the wall panel version. Make a variant here. I will make the usable version. And I will basically start to look at the geometry first here because this is the one that we are actually interacting with. So, it's it's definitely going to be very important to understand if art and animation have defined specific location for us to interact with. Right? Because in here, we have this center point that is also sometimes not even reachable here, but we don't really care because what we care is the description of the actions. But, with the wall panel, we'll just open the character tool. We just open the axis character, but it

  46. 00:36:09

    actually opens pretty much anything. And if we open like um this object, we see that we can debug through, for example, the joints and the joint name and the front part of the wall panel as something that we call anchor wall panel. And this is the position in which we expect the MPC to align. And this is the same position that we provided to the animation team to make sure that when they make the animation, these are perfectly aligned, you know, and they can perfectly align their hands to the right object, use the right grip, you know, when we play the procedural adjustment, and so on and so on. So, what we need to do in this case compared to the other ones is like first of all, we will add the usable component, of course.

  47. 00:36:57

    Second, these objects not really carriable. I don't really expect people to just, you know, take away like a wall panel from the ship. But we actually have a wall panel set up like like archetypes. And then we basically say, as we've seen in mannequin, there is a fragment tag for the wall panel. It's called wall panel. So, we can say, anytime we interact with this object, we carry the wall panel fragment tag with us and we propagate it through the chain. Now we do the alignment slot. The alignment slot in this case would still be called like a main alignment slot, but the helper name would be the one that we have seen here that is anchor wall panel. Let's copy it. Just don't want to misspell anything.

  48. 00:37:47

    And then we do the use slots. So, use slots in this case we need two versions, right? I mean, we could use also only one, but I think, you know, this is mostly for readability purpose. Use slot in like if you are to use slots, doesn't necessarily mean that two people can use it at the same time. Because when people can use it the same time when there is a combination of stuff that is the alignment slot you are in is free, the use slot that you are associated with is free, and the use channel you are, you know, you want to use it free. In our case we will have two use slots that they reference to the same alignment slot. So, you can't basically occupy the same alignment slot by two people and then it will not work. So, in this case you have like a top one that represents the top relay and then a bottom one that represents the bottom one.

  49. 00:38:37

    So, the fragment tag for the top one, it's going to be called high as we've seen in mannequin before. Now, what we do is that we add the use channel instances. So, what can we do on the wall panel top? We can look at here. If we search for wall panel, we can see we have a lot of actions. What we care today, we will try to limit to the things that we really care right now. And we can imagine that this open uh because we want to open it that panel. So, if it's closed, we will should not be able to take something. And what we will do with here is we will put it to the right alignment slot. And then we will add something that is called uh tags to add

  50. 00:39:26

    on enter and tags to remove on exit. What does this mean is that when I'm trying to use some object that is high or low, I want the player to know that he's interacting with the top or the bottom one to branch in the logic. So, what we'll do here, we will add a tag to the character automatically when he uses the top one. It's mentioning these are game tags as well, not to be These are game tags. That's a classic. Yes, things that it's really hard to follow sometimes cuz we call it all tags, but yeah, these are game tags. Maybe Dan can give like a little bit while I'm typing. Can you just give it up? So, so game tags are generally used I mean that they used in every game engine possible. Um they they're a good way of just keeping track of of literally anything that you want to

  51. 00:40:13

    any um game element to to do something essentially. So, if it's a chair, you might give it a tag for a chair, and then you could search for that chair through that game tag, for example. Um there's there's no end of ways you can use game tags. Whereas a mannequin tag is very specific to mannequin and the animations that are being played. So, a character, you know, that doesn't have any mannequin tags on them will do literally nothing. They'll just stand there. Um but then as you start adding those mannequin tags to the character, then they'll start collecting all of those go, "Oh, well, that means I must have to do this animation." And in here right now, when we're adding these fragment tags, we're saying that if you are in, for example, this alignment slot in front of the wall panel, you're probably going to get a wall panel fragment tag, say, and then that will just be one of

  52. 00:41:00

    those many tags that are required to get the wall panel specific animations. Um whereas a wall panel game tag would be used um elsewhere, like like say an NPC behavior, you would search for a wall panel tag to find that entity. You wouldn't search for a wall panel mannequin tag. Does that make sense? Yeah. Yeah. Is And also, yeah, we can do another thing that is called optional game tags. So, what it means is for this top used lot, we basically know that that one is tagged with a specific game tag. So, we say that every used channel, for example, that we interact with in here are related to the top um you know,

  53. 00:41:49

    interaction basically state or block. And to achieve that, we go to uh I call it um top Sorry, it's absorption generic location. The do the same with the bottom. So, this is going to be a bit of repetitive work. So, you know, you guys can talk while I just redo or repeat a bit of this uh Yeah, so this is what kind of doing right now I didn't know all of these game tags is so that he's able to reference those in these assumption logic because you you wouldn't reference like say mannequin tags in this assumption logic. So, you

  54. 00:42:37

    can say if this um if even the character has a game tag of um top on it, then make sure that you only play logic that is relevant to the top part of the wall panel. If he has a bottom game tag, then you could do logic that's specific to the bottom half of the gate the wall panel instead. So, basically the tags always we we kind of use the game tags to sort of able to differentiate in the behavior inside assumption. So, basically what Daniel said like um when you look at these these graphs in assumption, it's it's literally just to to like um be able to like take like either one path or another path based on the the game tags on the uh the entity. We use a lot of um logic gates in this assumption logic with tags. They're they're so fundamental in every game. I

  55. 00:43:27

    don't think you'll ever played a game, you know, at least in not my game that doesn't use tags in some way. Yeah, and tags are also like very important for us because they also represent traits skill and traits. And we can we can explain a little bit more of that. Oh, absolutely. Like for example, when you look at like a a spaceship, we we use the tags to be able to like differentiate is this like a like a combat ship or is it like a security ship or like is it a pirate ship or whatever like so. We also kind of use tags to be able to just to make like see the difference in like what type of, you know, enemy or what type of ship whatever that we're like using. Yeah, or even with these fuses as well. We we have game tags for is this damaged even? You know, so that would be the the thing that the NPC checks when they

  56. 00:44:16

    inspect it they go that they from the visual perspective it just goes oh I'm looking at this fuse, but on in the logic what we're doing was saying does this thing have the damaged tag on it? Because if it does then we want to make sure we repair it or replace it. If it doesn't then it's it's okay and we can just put it straight back in the wall panel. So these super parts with all game stack system. I think we will also do here right now is like this is like you know based on my basic template. So as you see in the default loadout still loads the relay that is not the usable which has been so we will basically just go through those objects and we also re replace the entity class name with the one that we want to really replace. So it's like in the template show usable we put the relay template show usable, the relay template show usable. We basically go in

  57. 00:45:05

    default loadout and we now add the sub component with a similar name. So as you see it's like if you have one type you just need you just need to populate it then it just propagates. You mentioned So Yeah, go. Obviously hierarchy is crucial. It's all all of this is this is the Russian nesting doll you mentioned. It's do tags have a priority? Are some tags more important than other tags? Like if an NPC recognizes a tag or like a conflicting tag or something does it does it prioritize one or the other or does it just jump up on the chair and not know what to do? I think that depends on the logic more than anything. I mean all tags are created equal. It's just how you use

  58. 00:45:54

    them. Um whereas mannequin tags they do have a priority so they will see um something like um uh say it was something more important like how to deal with a fire like I'm being shot. That's probably going to be a higher priority animation tag than, you know, just like a standard idle, for example. Or do you also have hierarchy in the in tags as far as I know? Like for instance for instance you can have an entity with like an outfit tag. You can have an entity with like a specific like very specific sort of outfit as well. So so you can sort of work with the hierarchy of tags as well. Never got if you want to sort of make anything like specific behavior based on the the hierarchical, you know, structure of the tags. Yeah, it really it's so

  59. 00:46:44

    fundamentally you can use them in pretty much any way you like. That's that's one of the best things about them. So here what we are finishing to set up is mostly the same things we did like down the the item parts to understand when things are attached to what. And then I think I jump I just skip this part to explain but basically we have also what we call the slotting setup, right? But we can show it a little bit in a in a little bit. So what we will do right now is we want to make sure that the you know that the engineer can actually find something broken, right? So we go back one second to the behavior and we say like okay we usually idle. But we want sometimes to search let's say right now in our test map that sometime we want to search for something else better to do, right? So

  60. 00:47:32

    instead of holding we just say like you know we will just not do anything or idle for something like between every two and three like and five seconds, right? So you can say like you know it starts two ways the basic duration then we can arrive up to five. So and every two three two five seconds we want to try to evaluate something else unless, you know, it immediately finds it. Let's say you want to handle broken like sub component. So, what we want to do is that we want to say this sub activity first of all is high priority compared to the idle. So, it should always be tried, you know, if possible. If possible means it needs to find some object that actually um is broken basically. So, you might want

  61. 00:48:21

    to call it uh uh sub component. So, it means that we need to search for any object in the world that is or I mean, not necessarily in the world, but like around us right now that is damaged. It would be like this global condition This is an item. So, these are the game tags. So, all the game tags. Yeah. And that is a sub component. See, the trick with the tank data space is trying to find a tank that already exists and trying to not create a new tag if it one of the tags already exist. Let's try to make it like that right

  62. 00:49:08

    now. If this gets selected, what we try to do is we basically say something. Since we don't have a line right now, we just create what we call bubbles that are like kind of a cartoon message on top of them. We say like, "I have found a broken sub component." 2 seconds and now we stay here. That we hold for now. Save. You know, we go in back in game. Close this. Now, what we will do is first we remove carriable the back draw. At least we got a bit less the back draw. And then we reload. Just this one. Go. Show. usable we put there all panel.

  63. 00:49:59

    We are doing that just to make it a bit simpler for the character to go. Then we try to see if right now it find something and it doesn't find anything. Why? Because there's nothing broken pretty much. So how do we simulate that? We could create like a little mission that just randomly, you know, puts the the subcomponents to to be broken. Sure. It's going to be take a little bit more time. We don't have so much time. So what we will do, we'll mostly just go in our version of the object and we just say that those are all broken. We just, you know, basically assign all the It's going to break them. Exactly, right? So it's a little same thing. Yeah, we just like actually started this one, but it is this one. So we save it now. So those objects are there. Usually just delete, we put it back. Now we

  64. 00:50:48

    should be able to in theory find this one, but there's no bubble on top. This is because usually we use this as a debug draw. So we need to enable this what we call the prototype dialog bubbles. Put it there. Look in here. Oh, I found the the broken subcomponent. But unfortunately, it doesn't do anything with that. So it's like, okay, what do we want to do? So now we can ask the NPC to go there and take it. All right, let's let's try to take it. So how do we do that? So it's like, okay, and so and by the way, is it where are those objects right now, right? So okay, we found them, but how do we know which one we found? The system automatically reports these objects into this this magic variable that get created when you create a new subactivity that is called required object search results. The only thing is we don't really know

  65. 00:51:37

    and we how when we're going to use it, right? Let's say you find 10 objects and there are 10 engineers, then I go to one, you go to another one, then I still think that it's broken because somebody reported it to me in the past. So, we still need to try to validate if this is still broken. Right now, for simplification we don't do that. Let's just see how it just first of all use that. So, let's say we want to use a carriable. So, we say like, you know what? I I know those objects are carriable for now. You know, I trust. And I just call it sub component. So, we can cast similar to how we do with code and eventually I really hope to get this away. You know, me and Tony have lots of good plans to make sure that this can automatically inherit and be transformed. But for now, we basically say we have a lot of objects that we want to cast into usable. The problem is

  66. 00:52:26

    you know, this is a lot of option. I want to have a bit more control. So, what I will do is I will probably just try to make a loop. And I will say I want to loop until I fail what I'm doing next. And what I'm doing next is mostly popping an object. So, I don't want to destroy this variable basically without being very careful. So, I want to remove from that variable one object at the at the time and make sure that we know what we are doing basically. Sub component object. So, we say like we take an object out of that and we put it into this other variable. Now, if this fails, it means there's no more object to do. So, we can just, you know, do something else. In our case here is

  67. 00:53:14

    like we could cast it to a usable. This could also fail. But this part, you know, in a way we don't really care right now. So, let's say we are okay handling this error with just suppressing the failure and say like, you know what? This is fine. For now. And if we need to do some logic because basically what is important to think is in the behavior flow logic is you want to handle the failure at the point in which you still have the context because the failure means something at that point. So in this case, failing means that I don't have any more object, but in this case it means this object is not the type that I am was expecting. So I could, in theory, add also something here that is um it's in core, I think, that we call bubble error that are a sort of this

  68. 00:54:03

    bubble that we use for prototype, but also important error similar to how we do code when we do assert and it's like, you know what, this logic is wrong. I think you wrote something previously that is wrong. It's reporting you some object that is not correct. Of course, it could be data error and this is why we don't crash like an assert might do in code, but you know, we still report it a bit harsh and there is a pop-up that comes out and says like, you know, are you sure you you know, you need to review your logic here. And in release, of course, this doesn't doesn't do anything. But anyway, we can remove this one. Now we have an object that Now we can do an action that is we want to use this object that is a usable. And what we can do here is we can take it. We walk to there, you know, and we just use whatever we can. Like if there are multiple use lot or whatever, but right now this is not really

  69. 00:54:51

    important. So let's see if this now works because there will be stuff that is missing. And you see this is this is failing right now. So why? Because right now this object is not just in the world. It's attached to other object and this is where we need to explain the system how the routing works. And routing means how a function call gets transported into the larger objects, for example. So it's like, well, I know you want to use the fuse, but to use the fuse you need to interact with the relay. You say, I know you want to interact with the relay, but to interact with the relay you actually need to use the wall panel, right? So what we'll do now is we will set up this information on the object here. So, maybe you guys

  70. 00:55:40

    can while I Yeah, while You're going into a little bit of overtime here. I'm just so the Yes, I I we finish this one and then I just show you the logic and I think you know, we need to shorten a little bit what I expected or we can just drag No, if it doesn't work we can just drag like the one that are everywhere and I can show you. Yeah, we haven't even started on the engineer behavior yet. I know, right? Very difficult difficult to cover such a big behavior in such a short amount of time. And it's one of the more complicate complicated behaviors that we've worked on, so as you all done. This one and the bartender are the really complicated one. Oh, we know how a complicated bartender is. Some of us did eight different segments on the bartender before it was done. Yeah. And we're going to call this part one then. Part one of many. Yeah, we'll we'll do part two engineer

  71. 00:56:28

    in a few weeks. So, busy what we are seeing here is that doing interact with the slots the slots of item two, we need to pass through the use slot main and then we already I was already setting up before just to speed up, but I think it didn't finish it. So, it's like there is team in the wall panel instead as you can see is that we have the status that that says that all the interact from the top you can you need to pass through the top high or top or bottom low use slot. So, we can now see. Delete this just for safety. See, the guy now moves there. He knows how to interact with that it's actually I I used the wrong alignment slot here.

  72. 00:57:17

    Seems like and this why it's not set up correctly. Let me try to look at which one I I wrote. Probably I copied the wrong one. For wall panel. Wall friend Wall friend But it's fine. Yeah. Wall friend is working. I'll pose I'll pose a question to everybody else. Mhm. Uh what why why do you NPCs love standing on chairs so much? I think friends answered that a few times already, haven't you? It's It's one of those things. I mean, I've I've been I've answered it when I've been doing star citizen streams, as well. It's It's one of those those kind of bugs that has the exact same visual output, but it has lots of different causes. Yeah, exactly. So, you you fix it one way, and then the next week you've you've got the exact same visual output, but it's a completely different bug. It's It's just one of those.

  73. 00:58:03

    Yeah, definitely. There's so many things going into like the usable code that you know, it's it's really a jungle sometimes to to sort of figure out what exactly is causing this bug, so. Yeah, definitely. It could be like a missing animation. It could be the animation name's changed. It could be the setup's changed slightly by accident in the parent above the variant or so. Could be absolutely anything. I I remember one recent. It was caused by people leaving the area. Then the NPCs that were still sitting in the seats, they basically got you know, turned off. And then when a player came back, they were turned back on, but the game didn't put them sitting correctly in the seats anymore, so they were just standing on them instead. Yeah, there are like tons of of problems basically that are causing that, and

  74. 00:58:51

    they're mostly coming from the streaming right now. This is why I like you know, I'm the first one that hates that bug, you know. It's just that I I think it's always like the problem is that the eyes at the end of the chain. So, every time something gets improved, right? And you know, we get this like this side effect that it all looked like the same bug. This is the wrong but most likely are not. So, we had like this as you see right now, he just took all the objects and he just dropped them all, of course. Like you know, but it's it's kind of cool. It just went with old animations and he played all all those objects. I never had that one, friend, so you're doing something new there. No, because I just looping I'm just looping through the day calling like right so he's like take one and he takes the next one he takes the next one he takes the next one and that's all he does right now. But it's uh yeah, for the standing on the chair basically this

  75. 00:59:39

    is what we are trying right now. I will want to basically dedicate some time we will dedicate some time to make a proper plan, you know, I am I'm scheduling sometimes because I'm I'm a bit tired of seeing it. Of course like eventually what my I really want to have like a proper animation of a guy standing on the chair for like just on purpose, you know. And it would be like gotcha, you know, and the place is like in 1,000 NPC. One in 1,000, you know, it will happen and you know, it will be very very fun. Yes, we need to do it. Uh but yeah, it's basically a lot to do sometimes for example, we don't know when something streams out that it will eventually come back. That we can't right now guarantee because we don't have yet the the proper persistence, you know, of that stuff. So it's like we

  76. 01:00:26

    we either reserve that object for somebody that might never come back or it might come back with a different idea right now and some sometimes and then it's like uh this was yours but now you can't use it because you reserved for somebody that is never going to come back. So we are not doing it and then of course sometimes what happens is, you know, another NPC actually sits there before and this when you see sometimes two NPC one next to each other but the streaming takes too long, you know, and then the guys are already there but they're also in place already lots of uh fallbacks and whenever we find them we basically had them and then we try to recover from some of the situations right now as well. Uh so that there is a lot of little piece because with the population manager of course this is meant to be different, right? When when NPCs goes away, you know, those will be repopulated by the population manager.

  77. 01:01:14

    So this is why like in a way this is not real a problem that will exist in the future, all right, you know, because it's a basically with our plan that is already a known problem in a way of the fact that the guys just come back for just because the stream is the streaming kicks in, right? But then there is like of course the stuff that there might be some bug sometimes with the with the LOD update. We try to be efficient in updating stuff that is not visible and maybe that one failed to attach, you know, and we are we are searching for some of this stuff. So there is like, yeah, as Dan said, same visual problem with with several bugs that we are, you know, constantly fixing and some new optimization things might still kick back. Anyway, I think we are pretty much like at the end, but the only thing I wanted to show you is basically these things how the actual logic works. You know,

  78. 01:02:03

    it's going to be like just the last 2 minutes. If we go in the world panel when we do take, what do we do? We basically still say like, oh, I want to open the panel, no matter what. I want to try to open it. And then in the open, this is where all the game tags we have set up come into play. Because basically we what what we try to do is, for example, we try to see say, are we on the top, are interacting with top, or are we interacting with bottom? I mean, this is really for safety because in theory if you're not interacting with top, you should be interacting with bottom. But then we say like, oh, is the object actually having some tags like easy open? If it's not open, right, then we want to open it. But if it's open, that's fine. So it's a sort of like building on top of the logic we already have without having to duplicate too much logic, right? Because at the end of the use channels for our, you know, internal logic, I just functions. We can

  79. 01:02:51

    just call a function and then just let them execute if necessary, right? And of course like whenever we see like is this really a problem or performance or something, then we can have some early out or double checks and we can optimize this. But this gives us like a very scalable solution first of all for the logic, you know. And and then the take says like, okay, after open, now I'm in a state in which I know that it's been open. The player could have opened before, right? Even if the eye is really precise, we'll always close all the all the doors. We can never guarantee that, you know, because prey could troll around. Or actually might have forgotten because maybe I don't know, the eye as well. Maybe combat started while they were repairing something, right? And now they are back after 1 hour. that we're Yeah, it also means that we're able to have NPC behavior that just goes around closing all the wall panels. Absolutely. And then they say, "Oh, who

  80. 01:03:39

    opened that?" Actually, it could even feel wrong like, you know, there could be guys in a state in which they say, "I expect everything to be closed. If something has opened, maybe there's somebody here I'm not expecting, right?" And this we could also build on top of that. It's going to be one of those guys with a javelin just walking around closing all the doors. "Excuse me, hot man. There's somebody always opening these wall panels." And that's why it's so cool, I'm sorry I interrupted you. That's why it's so cool, man. I was just saying it it like substantially it's like super generic like in in like how we sort of modularized it and split up everything into tasks. And that's what makes it so cool because we can sort of do whatever we basically want, you know, we can we can chain the tasks in every way we want and we can sort of make like like so many different behaviors like because of this modularity.

  81. 01:04:26

    And this is the other magic magic task that is taking all the data we put it there and says which object which mannequin tags I need to use to interact with that object. And then it will get that one from the item port and then we merge it from, you know, it's like there's like some variable here that get populated by the code that says like, "Oh, you you're already in a take." That means that you already need to use take for your action. You already need to use wall panel because we propagate there. And then we also can guarantee that for example we can say like, "You know what? You're trying to take the wall panel. You just can't do it." But if you're taking something inside, we can always we have two variables that basically tells us which usable we are in. In this case for example, the usable variable contains the wall panel and it's like we want to open and wall panel. We don't want to take the wall panel, but then we want to interact with a way with the item to

  82. 01:05:17

    take, you know, that is actually coming as well from the routing, you know, and it's the initial routing usable that is like I started from the fuse and I arrived to the wall panel. So, we have all these little pieces that has been, you know, implemented in all those years basically, you know, and especially with the bartender helped us a lot and the engineering is helping us a lot, you know, then basically started to do this use channel inception, you know, and I was and I being was like, "Oh, oh my god, then it's like yeah, this is scary." And I was like, "Actually, it's really cool, you know, and then we can make it working very well." And It's literally the only thing that, you know, only designer could think of that. Yeah, yeah, no, no, I was like and I usually know you say, "If it's possible in the tool, you guys will do it 100%." Like you.

  83. 01:06:03

    I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I think we could probably do a better job of simplifying this because we're kind of we're kind of what we're what we're going through right now is is years worth of, you know, research and tech development and we're just kind of coming out as probably a bit of verbal diarrhea, but it's it's um We need to We need to make it faster for designers. This is These are our next goal is of course like for example, we have a tool we are working on that is the usable builder, right? I think some

  84. 01:06:50

    of those features are not yet supported in there. That is why I'm I didn't show it today, but the goal is to have these tools where, you know, you have a bit a bit easier like click approach compared to like the data for our structure is mostly, you know, it's this data content, but you know, you don't necessarily have to interact with that, right? It's like you might have a tool that is much more visual that allows you to you know to click here and say, "Oh, I click on this item part." Cool, I want to add this data directly and then it automatically propagates, right? This is our goal. You build the system and then you build the tools to make the system Absolutely. Yeah. Sometimes you do it in parallel, but you know, that means also you're a bit slower in developing the system and it depends but on the priority of the company as well what you want to deliver. I mean, it was only a couple years ago that the concept of views channels didn't even exist.

  85. 01:07:38

    And yet we still had views channels in the game. Well, we've got a little over 1,200 people watching live who all are ready to create NPCs now. Thanks to guys for you know all the attention that you gave us. I hope like again it for me it feels always like that is not enough what I'm showing, right? But, I think it could be nice to also get the feedback from people like whatever they want to see we can show it next time, you know. Uh Hayden, I before I let you go I have to mention your your your RGB chair. Well, thanks you guys. Where did you get your RGB chair? It's the 100 million PewDiePie limited edition chair. I have to represent. Oh, no. Yeah, I'm one of them. I'm sorry. This great career went straight down the

  86. 01:08:25

    toilet. Last day one, come on. All right. Well, that's where that's where we'll end the show. Uh thanks Fran, Dan, Jacob, Idris, and Hayden. Uh thank you for taking the time out of the end of your week uh to be here on the show. I I understand you're the only studio that doesn't have Monday off, right? No. I did but the third is off in in Germany. So, we have we have Yeah, you guys you guys have plenty of bank holidays, but you you enjoy the the one day you guys have to work and we'll all beyond on Monday. It'd be so quiet. All right. Thank you everybody. Guys, this has been Star Citizen Live Game Dev building NPC behaviors. I'm was your I was your host Jared Huckaby.

  87. 01:09:16

    We'll see you next week everybody. Take care. Bye. Bye guys. It was a pleasure. See you. Bye ciao. PewDiePie chair? Really? That's

Transcript from YouTube’s automatic captions — punctuation and Star Citizen jargon are approximate. The video itself is hosted by CIG on the official channel.

Squadron 42

SQ42 Launch Subathon

$2,115of $3,000

Getting Sub to Manchester for the Squadron 42 launch

Next giveawaySubscriber Store pick
$35to go