Game Development Community

Behavior/Component System discussion

by Jeff Raab · in Torque 3D Professional · 06/02/2013 (6:36 am) · 63 replies

It seemed like a better idea to do proper discussion about what my blog covered in a forum thread, since they're, you know, for discussing.

So this thread is more or less going to be about 2 things. Release plans, and suggestions on what behaviors/components should come with as a starter/example set.

I mentioned in my comment that my personal goal with the Actor class and it's use of components is to pretty much get rid of ShapeBase and most of the need for specialized object classes derived from it by exploiting the behaviors system.
So any suggestions on examples are welcome, even if it's something like 'the ShapeBaseImage state machine as a behavior' or 'the entire player physics/movement code'. Lets just throw ideas at the wall and see which ideas stick as a good starting batch out the door.

Ones that will be released with this, regardless:

Core behaviors:
BaseBehavior - script-only behavior, no engine side work, general purpose for gameplay stuff
RenderBehavior - core render behavior template that other render behaviors would derive from
TickBehavior - hooks with Actor's processTick allowing you to do ticked code with the behaviors
NetworkBehavior - this will be useful as a more direct approach to gameplay/event feedback to the client than having to jump hoops through the commandTo* calls.

Unique Behaviors:
RenderShape - accepts a shape file, and renders it
RenderBillboard - accepts a material and renders a billboard of it
AnimationController - if you have a RenderShape, you can do this, and have the ability to animate the shape. What animations can be used will be entirely script defined. No need for the ActionAnimationList.

ControlObject - this lets a client take control of this object. Allows you to make use of the next behavior...
UpdateMove - this lets you intercept the move updates from a controller object and move the shape around


This is what I've got slated thus far. Please throw out your own suggestions and we can try and hash out a solid list of things people need/want to see when it comes out.
Page «Previous 1 2 3 4 Last »
#1
06/02/2013 (10:05 am)
I'm actually pretty excited that this is a reality. Dan Webb and I were chatting earlier, and both quite happy to be part of a community buyout, since that's the route you mentioned taking.

In terms of functionality, I think there are two more key behaviors: physics and collision. The most basic physics behavior, of course, would basically be the Item physics code, which does no rotation, just bounces around with gravity. And to match it, the most basic collision behavior would be the AABB that the Player (and Item as well) currently uses.

But these should be just starting points - for example, a capsule collision behavior for Players would be great. PhysX and Bullet should have their own collision/physics behaviors.

The Player class is basically a combination of Item's physics, input that calculates acceleration, and simple collision. Plus all the arm/head animation stuff, which involves a lot more attention to detail (see the contents of writePacketData). Plus movement animations, which should be replaced by a generic state machine behavior.

I'd also vote for a 'simple animation' behavior that allows you to rotate or bounce things with simple constant velocity or equations.

I think we also shouldn't overlook Camera as a candidate for behaviorising! Camera controls are really important, and being able to control the camera means being able to create a ton of gametypes. What separates a 2.5d sidescroller from an FPS? A large part of it is the camera, and the differences in controls and level design follow on from there.

I'd be willing to put some time towards these suggestions depending on how you want things to progress, Jeff. I also sense I'll need to rename the Behavior class in that AI framework I was working on ;P.

EDIT: Forgot to mention. I think it's important to make sure that script methods get passed around to behaviors. For example, if I call setMoveDestination on a composite object, I want the first (or maybe all) AI behavior to respond to that method call, rather than the Actor itself, which obviously won't have a response for it. I'm pretty sure T2D does something like this.
#2
06/02/2013 (12:26 pm)
I have yet to pull myself together and read the whole blog post.. But this looks awesome!

One thing I thought about tho was support for some kind of "object prefab", right now it looks like you have too add all the behaviours whenever you create a new object. It would be nice if behaviours could be added to datablocks or something similar to that, so you can create some base classes in script instead of having a "add-behaviours" function for each of your classes that adds the behaviour.
#3
06/02/2013 (1:40 pm)
looks interesting
it might be a good idea to lookup the GMK scripts
as GMK`s Templates implementation is actually nothing less then what Behaviours are on your end
#4
06/02/2013 (5:54 pm)
Just wondering, could this behaviour based approach help in turning particle emitters into light sources? At present, all my campfires are prefabs made up of 2 particle emitters (fire and smoke) and a point light. I grab my campfire from the prefabs tab and place it. It works well, but as every campfire will share the same light animations, it'd be nice to circumvent having to create multiple prefabs (to avoid repetition) by altering the campfireEmitter behaviour to be a point light.

I just woke up, so maybe I'm talking crap.
#5
06/02/2013 (8:28 pm)
@Lukas
I actually mention this in the blog. I plan on having it where you can r-click on an actor object in the scene tree view, and get an option to 'Save to Script', letting you pick where the datablock and scripts are saved, etc.
Then the datablock would have the onAdd callback, which it would build in the calls to add the existing behaviors so when you create an instance of your object via the datablock, it adds the behaviors.
In short, you rapidly build out the object in the editor, and then can choose to leave it as a mission-specific object, or save it to scripts for reuse.

@J0
I glanced through the template system, and while kinda similar, it's script based and pretty much enacts behavior-esque properties ontop of existing classes.
This is built from the core up as a unique object purpose-built for behavior/components. But it is somewhat similar in spirit.

@Dan
You could easily draft up behaviors that would add lights, or add particle effects etc.
Assuming you did that, you could have a datablock Actor(as described above) which has a particle and light behavior and drop it down as an instance.
Depending on how the behaviors are made, they could easily be set up to override the datablocks for the particles/light settings, so you start with a prefab campfire, and then can tweak each to have uniqueness to them. Different flicker rates and so on. So yes, that sort of thing is totally doable.

Heck, you could, instead of having a behavior that creates a particle emitter, have a behavior that literally just acts as an emitter, skipping the middleman. From there all the properties can be dynamic, defined via the behavior instead of needing the datablocks. Thus making it even more flexible.

@Daniel
Physics and Collisions would functionally be subsets of the TickBehavior, but they are pretty critical, I concur.
I suppose a really good proof-of-concept to it, as well as building a solid library of starter behaviors would to be basically have enough behaviors that you could readily replicate the existing player class with nothing but behaviors.
As for the physics behavior, instead of having unique ones for Torque Physics, and PhysX or Bullet, it'd be smarter to have one physics behavior that uses the engine defines to discern what library to use.
That way you don't need to remember if the project is using Bullet or whatever. Just drop a physicsBehavior on there and it does the selection in the background.

A simple animation behavior would be a good example, and stupid easy to do. TickBehavior that on-tick, rotates or moves the object at a set speed or whatnot. That'd be a nice, simple example :)

As for the camera, I definitely, definitely concur. I hadn't finished my run through of how the camera interacts with other controlled objects, but I agree you need to be able to drop a camera behavior onto an object for the camera to follow the object around, etc. So that needs some hashing out.

Also, yes method calls should be getting passed(though I haven't gotten lots of testing for cross-pollenization yet). It's based on an expanded version of the existing behavior/component code in T3D, which is in turn based of T2D's stuff.
So outside any fixes/expansions that MIGHT need adding, it looks like that part is in and just needs some thorough testing.
#6
06/02/2013 (11:46 pm)
Don't forget interpolation in those ticking behaviors, especially when talking about animation. Yeah, keeping the physics behaviors to 'simple' (Item) and 'advanced' (which uses whatever is available, or RigidShape if nothing else) is a better idea.

Adding light and particles directly from a behavior is exactly the way to go, IMO.

In terms of the camera, I wonder if something like constraints might be a good way to go. You add a camera object, then give it a constraint behavior that makes it track some location, or lock XY coordinates with another object, or whatever. Though a single 'I own the camera' behavior could be helpful, it just doesn't sound all that flexible. I guess both options should be available ;P.
#7
06/03/2013 (7:44 am)
Am I a bit sick in the head for finding this to be something of a turn-on? Meooow!

This is awesome Jeff. :)
#8
06/03/2013 (8:46 am)
Hahaha, Dan :)

@Daniel
I figure the Actor class will interpolate it's transform at least. Anything fancier can be handled through the behaviors.

Still not positive on the camera front, because how the camera behaves kind of locks in through the ControlObject method.

My current thoughts on it are, you add a control object behavior, and naturally the camera is thus 'attached' to the Actor being controlled. By default it can just use the actor transform.

From there, you can attach camera behaviors, which would enact the different camera types, such as orbit, tracking, mounted to a given node - as well as all the various minor settings, like offset transforms, FOVs and so on.
Heck, you could even look at having the Control Object behavior track the number of camera behaviors on the object, and let you pick between them, so you could set up different views by attaching additional camera behaviors.

I also went and ran through the callback code last night.
I ended up adding two-way namespace code(which was...interesting)
The reason being, that by default, the component system already attempts to make use of any behaviors namespaces when trying to do function calls.

So if you do:
%actorObj.foo();

It'll check both the actual %actorObj's namespaces as well as any behaviors on it.
This is largely fine, and the behaviors use their template's namespace.
The only problem was this caused namespace conflicts when you wanted a behavior to have console methods back into the behavior instance to do stuff.

Like on our renderShapeBehavior. Say I have a method that fetches the shape bounds because my code might need it.
You would run into the problem where you'd try and get your behavior instance, and then call your getShapeBounds function from it, but it's using the template or actor namespace, which naturally doesn't have that method.

So I implemented a two-way namespace setup, where it checks both the template and instance's namespaces for relevant methods it can call.
The order of operations is thus: Instance->Template->Owner.

This should give looooads of flexibility to the whole thing, especially script-side.
#9
06/04/2013 (5:25 am)
Quote:My current thoughts on it are, you add a control object behavior, and naturally the camera is thus 'attached' to the Actor being controlled. By default it can just use the actor transform.
If we're talking about ideals, I think it should be much more loosely coupled. Instead of a single 'control object', there should be an 'input' behavior. All input behaviors should respond to inputs from the client they're associated with. IMO, this is better practise, and would allow more flexible prototyping of more game ideas. For example, I just saw Swapper, where you can create multiple avatars that all respond to your inputs identically - it's a puzzle game. Right now in T3D that's basically impossible due to the control object paradigm. In T2D it's easy as pie, since you just bind events however you like. I think a goal of a system like this should be to make T3D more flexible*, not replicate existing features in a different paradigm.

If we're talking about practicality, though, what you say sounds fine. I don't think you particularly want to rewrite such a core element of T3D like the input handling for an initial release ;P.

*I should note that this is exactly what you are doing - making T3D more flexible - and I salute you for it. This is why I'm pushing that hard, because I think it's fantastic and needs to be concentrated on. Frankly, this sort of system would have made binary-only T3D in the InstantAction days really good.

EDIT: And continuing that line of thought, 'control object' and 'camera' need to be completely separate IMO.
#10
06/04/2013 (6:37 am)
Yeah, I agree.
The problem is, is that the control object stuff is pretty ingrained and touches quite a bit of stuff. It definitely should be pulled out so you can get more flexible stuff, but I think that's a good 'stage 2' for this.

In the short term, replicating the existing behavior keeps the pace fast, and once it's out in the open, there's more breathing room to nitpick parts of the core engine that get in the way.

That said...for the control bindings, you may be able to kinda-sorta do it where it is now.
I need to test that sorta thing, but I mentioned the NetworkedBehavior. Which would let you readily transmit data/events between server and client.
In theory you could subclass a networkBehavior to be a input behavior. When it's added, to a controlled object, it throws an event back to the client, and could add a keybind to the movemap, as the behavior describes.

It's not perfect, but it'd be a starting point without having to overhaul the entire controlObject stuff right away.

Also, was looking through options for the community purchase angle, and due to infrastructure and whatnot, I'm looking at probably doing an indie gogo campaign for it(to avoid people just dumping money into a paypal until I have enough, which feels far too shady for me, lol)
I was mulling on how many hours I'd dumped into this so far and came up with a figure of about $700 being the development worth of the project, which would be my initial estimate for the community purchase price.

Does everyone think this sounds like a fair amount?
#11
06/04/2013 (10:51 am)
Could someone explain this a bit more to me?

So, you would have a control object,
then add a Camera Behavior,
then a player behavior,
then add network behavior?

I've meddled in the network stack here and there, so I kinda have a idea what the current implementation chews up bandwidth wise. So I'm curious about the network changes and how/if they would be isolated since each behavior would have it's own network information, right?

Then, in regards to the c++, wouldn't you have to re-write all of the T3D classes into behaviors instead of sceneobjects?

I mean, you wouldn't have a player object anymore, it would be a combination of behaviors that define a player?

This concept is kinda new to me, but is the idea to define the objects in game by the collection of behaviors defined to them and not so much as atom objects?
#12
06/04/2013 (11:11 am)
I'm certainly interested in a more componentized approach to T3D. This sort of effort is exactly the kind of thing that the Committee has discussed about wanting to see as a long-term goal and would pave the way to finally cleaning up the T3D folder (and subsequent Shapebase bloat) in the source.
#13
06/04/2013 (1:53 pm)
@Jeff I know I would be "pledging" about 20-40$ on this, if like-minded people pledge about the same amount, thats about 23-35 pledgers needed so seems reasonable given theres ~1300 stars on the T3D Github page.

Although have you thought about whether you would be doing stretch-goals in the case of using IGG?
(Also remember to calculate the amount of money IGG takes for running the campaign)
#14
06/04/2013 (2:09 pm)
@Vince
You've more or less got it. It would be more granular than a 'player behavior'

I'm still hashing out the specific behaviors, but if I gave a guess at what a player object would look like:

ControlObjectBehavior
CameraBehavior
InputBehavior(s) - (As explained above, this may not work without reworking the control object code at the moment)
RenderBehavior
AnimationControlBehavior
MoveCollisionBehavior

I think that'd cover most of the bases of the player class functionality.

As for network weight, it should actually be rather light. The behaviors are all networked, but they inherit right from netobject, and individually pass minimal amounts of data per update. They're designed to cross reference as needed. The Actor class is a bit heavier as it stems from gameBase, but otherwise transfers minimal amounts of data. Actor right now by itself transfers transform data(using a mask) and behavior ids so the actor class has a up to date list of behaviors(using a separate mask).
Each behavior coming off the main template and instance classes will at least make sure to pass the behavior owner ghost id and template ghost id. That way the behaviors can be referenced on the client as needed. Again, this gets it's own mask and is only called as needed, usually those don't change.
From there, each particular behavior can use it's own masks to filter updates for more complicated stuff like animation updates to keep the network noise to a minimum.
Because the behaviors are separate, but cross reference, you avoid the current situation in shapebase where it's using a majority of available bit space for masks leaving tons of room for expansion and keeping noise to a minimum.

For the engine/class rewrites. That's my ideal goal for this. Eventually we can gut out most of the main classes in the T3D folder and just have a large, intelligent spread of behaviors to replicate the same functionality. This gives us the same capabilities, but far more flexibile and efficient. It would also cut down how much non engine coders would need to go into the engine to get their game working.

@Michael
That's the plan ;)

@Lukas
Yeah, I figure it's a reasonable amount for the work involved so far and doesn't put a big strain on each person to contribute. I mean, sure it'd be super-cool for people to totally want to throw a million bucks at me, but it's not really practical for them or myself :P
As for stretch goals, it's an interesting idea, but the only thing I can think that it would impact is the number of behaviors I would personally put together and release out at launch.
I mean, it might work, but I dunno how much interest there would be in stretch goals(or how to price them, some behaviors are pretty simple, others are a lot more complicated like the MoveCollsion behavior which replicates the player movement/collison code - which will be in at launch anyways)
#15
06/06/2013 (7:10 am)
Alright, I haven't seen a post for like, a WHOLE DAY, so I figure it's time for a progress report.

From the pictures in the blog, the renderShape behavior was already in.
Since then, I'd been working on collision behaviors.

The MoveCollisionBehavior is largely in. It's intended to replicate the player-type dynamic object collisions.
It pushes it's collision checks based on the object velocity(trying to determine a behavior agnostic way to track this) and will detect collisions. It'll also do callbacks, tracking what it hit, etc, etc.

Next is StaticCollisionBehavior.
This basically replicates the collision rules for TSStatic. Used for, as it says, static, non-animating objects(it should work for moving, non-animating objects, but really that's what the prior behavior is for)
It supports no collision, bounds, collision mesh and visible.
It's mostly in, but there's still some wonkiness about dynamic objects(like the player) colliding, so I just have to iron those bugs out.

Last is the RaycastCollisionBehavior.
Again, what it says on the tin. It's specifically for raycast checks. Supports none, bounds, collision mesh(may later special-case named hitboxes for player objects) and visible.
Visible is really intended for static, non-animating shapes, but THEORETICALLY works elsewhere. Not that I'd try it.
This is in and works pretty much perfectly.

I also want to have a Non-obstructing collision mode on all of these, where it'll detect the collision, trigger it's callbacks, but doesn't obstruct the collider. This would be great for non-polyhedral trigger objects, water objects or other such fanciful things.

Also squashed quite a few bugs making sure all the inter-operability works right and whatnot. I still need to have some sanity/dependency checks, and some feedback on that, but it's cruising along pretty nicely.

Another feature I'm looking into is source-script loading. Torque tracks the source script files where an object, such as the behavior template, is loaded from.
I'm looking at having a button in the behavior block that you can click, and it loads a text editor window of the source script file. Then you would edit the script(maybe adding an additional field to the template, or fixing a bug in the called functions), and save and close.
Then it would delete the behavior off the actor object, delete the existing template, and re-exec the script file, reloading everything. After it's reloaded, it would re-add the behavior to the object, and would thus get updated functionality/fields.

So in essence, in the same way behaviors remove a lot of the need for going into script to make objects and gameplay, this would remove a lot of the need to go into script to make behaviors and fixes.
#16
06/06/2013 (7:30 am)
Source-script laoding:
there was/ is a t3d editor script resource that u might be able to hook in
only thing it has no syntax higlting and undo function
but it seems good as a starting base - but hey who knows maybe already got a solution?

Resource Link:
www.garagegames.com/community/resources/view/20567
#17
06/06/2013 (7:33 am)
I'd actually been aware of that from when it came out. I hashed out my own update to it that included syntax highlighting and other good stuff, but there were a couple bugs that necessitated additional attention I couldn't give it at the time. For the moment, I'll probably go with a tweaked version of the Text Editor already in T3D(used for the command fields).

Later, I'll fix the bugs in my more feature-filled script editor, and hook it in.
#18
06/07/2013 (1:04 am)
Oh heres a thing, what if you for example want 2 of the same type of components? Does it support that or will you have to create a container component?

Also it would be nice if there were some system to organize the components into sub-folder so you don't have a mile-long list of fields etc but can have the components sorted in e.g. "rendering" "gameplay" that you can collapse and display at will.
#19
06/07/2013 (6:25 am)
I think how well that would work would be dependant on the component.
I'm working on tweaking the sorting/passing of components for more complex ones, but for example, the way that raycasts feed data necessitates(currently) a pass/fail return, which is really hard to do right if you let it chew through multiple raycast collider behaviors. So that currently returns the first one it finds.

I plan to add flags for both dependencies and if the behavior must be unique or not.
If the behavior is unique then the editor can reject adding duplicates, etc.
Some behaviors, like inputs or other such things are totally valid to have multiples, and shouldn't generate any conflicts.

For the organization thing, I think that's a pretty good idea, but I don't think it auto-organizing would be good.
I'll look at adding an optional input, a sort name for each behavior. If it has a sort name, it gets put into a rollout container for all behaviors that share the sort group.
#20
06/25/2013 (8:38 pm)
Have you been thinking about how this system will apply to AI at all? I had a look back over the AI framework I was writing (trying to start that train up again) and thinking that adding behaviors would be a great way to represent different AI capabilities/goals.

I ended up using objects' spawn scripts to give them different starting behaviors, like patrolling a path. Behavior instances could solve that.

Even better, IMO, behaviors could be used to declare passive behavior. For example, at the moment my sensor systems fire a ton of callbacks that are intercepted in scripts and used to run actions. For example, if an AI notices something in the corner of their eye, then a LookAt action gets chucked onto the action manager, and depending on what other actions are competing to use the character's head, it may or may not glance over to get a better look.

This behavior could be completely decoupled using behaviors - just add a 'look at things when you notice them' behavior, which responds to a sensor callback in script. Funnily enough, I was already doing this with my own Behavior class, but it was AI-specific. I'm thinking I will halt work on my Behavior class and focus on just the action manager - when/if your stuff gets added to Torque, it should replace my own behaviors.

Further, behaviors could be used as 'goals' in goal-based AI. That means, basically, that the AI has several things it wants to do - for example, staying alive, attacking enemies, patrolling a path, etc. At any given moment it decides what the most important goal to follow is, and makes an action plan accordingly. (HTN planning and GOAP both fall under this paradigm. HTN seems to operate on discrete goals, whereas a GOAP goal is just a world state with many parameters.) The goals an AI character has could be represented by what behaviors are attached. Each behavior could accept sensor callbacks and update its own priority based on the current perceived state of the AI world. Then a periodic callback just inspects all the goal behaviors, selects the one with the highest priority, and acts accordingly.

This last paragraph actually seems like a bit of an abuse of the system, since goals and behaviors are conceptually separate. Though it sounds like a possible and helpful way to implement them.
Page «Previous 1 2 3 4 Last »