Jump to content
  • entries
    945
  • comments
    5,899
  • views
    930,076

A first look at entity scripts


Josh

4,325 views

 Share

In Leadwerks Engine 3, you can load a script and attach it to any entity. You can attach multiple scripts to any entity, and they will be called in the order they were attached. Right now, I am calling the script-side table "actor" because it is a little more descriptive than "object" but I'm not sure about all the syntax yet. Below is a sample script for a sliding door. When you attach this to a model, the script will control its behavior:

-----------------------------
-- Sliding door script
-----------------------------

--Attach this to any entity to turn it into a sliding door.
--You can make the door move in any direction by adjusting the movement vector.
--When the door opens or closes, a one-shot noise will play, along with looping
--sound that will continue until the door comes to rest.

--expose Sound opennoise
--expose Sound closenoise
--expose Sound movenoise
--expose Sound stopnoise
--expose Vec3 movement
--expose function Open
--expose function Close

function actor:Start()
if self.movement~=nil then
	self.openposition = self.entity.position + movement
	self.closeposition = self.entity.position
end
end

function actor:Open()
if self.openstate==0 then
	self.movestate=1

	--Play one-shot noise, if it is set
	if self.opennoise~=nil then
		self.entity:EmitSound(self.opennoise)
	end

	--Play looping move noise if it is set
	if self.movenoise~=nil
		self.movesource = self.entity:EmitSound(self.movenoise,true)
	end
end
end

function actor:Close()
if self.openstate==1 then
	self.movestate=-1		

	--Play one-shot noise, if it is set
	if self.closenoise~=nil then
		self.entity:EmitSound(self.closenoise)
	end

	--Play looping move noise if it is set
	if self.movenoise~=nil
		self.movesource = self.entity:EmitSound(self.movenoise,true)
	end
end
end

function actor:Update()
local d
local l

if self.movestate~=0

	--Calculate the difference between where we are and where we should be
	if self.openstate==1
		d = self.openposition - self.entity.position		
	else
		d = self.closeposition - self.entity.position
	end

	--Check to see if there is any difference
	l=d:Length()
	if l>0 then

		--Limit the difference if it is greater than the move speed of the door
		l = d:Length()
		if l>self.movespeed
			d = d:Normalize() * l
		end

		self.entity:Move(d,false)
	else
		self.movestate=0

		--Disable looping noise source if it exists
		if self.movesource~=nil then self.movesource:Stop()

		--Play one-shot stop noise if it exists
		if self.stopnoise~=nil then self.entity:Emit(self.stopnoise)
	end

end
end

Lua is pretty flexible, so I can make it work pretty much any way we want. When designing stuff like this, I find it's best to start with what the end user wants, and then work your way backwards to make it happen. What do you think?

 Share

15 Comments


Recommended Comments

I assume Start() and Update() are called by the engine and that Open() and Close() would be something that the user would have to call from other entities? If that's the case how would we make those calls since this is actor "class" and every script, from what you've described, would be an actor "class". How would we differentiate between scripts attached to specific objects to call their specific functions?

 

Also, possibly off topic but specific to this situation with no physics involved, you might want to get a tweening library built into LE. I worked with iTween which is a library some guy created for Unity which he gives away for free and it makes moving stuff like this, non physics stuff, amazingly simple. I don't think there is any reason it needs to be tightly bound to an engine so you might want to talk with the guy to see if he can convert it to lua for you? http://itween.pixelplacement.com/index.php All that code you have for doing this could be condensed into a few lines (possibly 1 or 2) with such a library. Believe me your users (especially the non programmers and really even the programmers I guess) will love you for doing it, and scripting interactions would be so much easier.

Link to comment

You could call Open() and Close() from other scripts, or from a C++ program (something like entity->CallActor("Open")) but I think we've found none of those approaches really make game interactions very easy. You generally don't know what functions other script objects have, and making generic "Activate" and "Enable" functions for each one doesn't seem to yield very good results, either.

 

My primary concern for Leadwerks Engine 3 is that historically, with every 3D engine or game creation system, only about 10% of the users can successfully create game interactions with them. Then there are ones that make it easy to do a few pre-programmed interactions, but very few can make anything of their own and most end up with very few changes to the original. This is a huge problem.

 

So keeping that in mind, the main way to access the script functions of an entity is through the flowgraph, which I will show as it develops. You script your behavior, attach it to an entity, and then you can control the way things interact visually. There's no guessing what the door's functions are, or checking the script, because it appears right in the flowgraph editor, so it's obvious. So you have a scripted button, and this scripted door, and they can be combined without even looking at the scripts. So right off the bat, a non-programmer can control interactions in a way that's beyond what most programmers currently do, including myself. It's not like it's hard to program that specific behavior, but without a general interactions system, it's just so much trouble that you generally don't bother to do it. The idea in LE2 was that the script function for SetEntityKey() could be used for this kind of functionality, but I think without a visual display of everything you have access to, it's not much fun.

 

This also opens up Leadwerks Engine to a new category of users: designers. They can take place objects in a scene, attach scripts, and set up their interactions without looking at one line of code. This is actually pretty efficient because a script programmer can design different behaviors, and then give them to the designer to produce a level. I think this will also facilitate code sharing. Sure, I can program my own stuff, but it would be cool to just download a useful script and play with it, knowing I'm not going to have a bunch of incompatibilities or requirements.

 

I plan on providing some generic "mover" scripts that handle movement interpolation. You just set a few values in the editor the script handles the rest.

Link to comment

So you have a scripted button, and this scripted door, and they can be combined without even looking at the scripts.

 

So your scripts would require input/output. Like your button would require to fire an event (which I assume would be checked inside it's Update() method), which you can then attach to the doors Open() method (for example).

 

That seems logical, but sounds like your actor scripts are going to require an output mechanism which at it's core is probably just a table that holds functions (all the inputs tied to an output). Also think about functions that may need parameters and how to handle variables that one might need.

Link to comment
So your scripts would require input/output. Like your button would require to fire an event (which I assume would be checked inside it's Update() method), which you can then attach to the doors Open() method (for example).

It might be possible to make Lua automatically execute all outputs when a certain function is called. Otherwise, you'll just have something like this at the end of the Open() function:

CallOutputs("Open")

 

This can be extended in the future to take function arguments.

 

The flowgraph isn't really about programming though, it's about connecting objects to make events occur.

Link to comment

The flowgraph isn't really about programming though, it's about connecting objects to make events occur.

 

That's pretty much programming though. Without taking it to that next step you aren't going to end up with much different then you do now. You'll just have more doors opening and closing which isn't all that exciting. With each LE version you take it slightly further inevitably (the way I see it) ending towards a flowgraph for everything. You should take it there now and not wait until LE 4 :)

Link to comment

I know you like the idea of programming with a visual designer, and it's a cool idea, but I don't think the outcome would be as good for my users. I think complex behaviors should be programmed and then combined and linked visually. I'm sure we'll learn more as time goes on and we see these systems in action.

Link to comment

I think complex behaviors should be programmed and then combined and linked visually.

 

Interestingly enough the complex behaviors could even be programmed visually, but that doesn't need to be your system. I think that would fit into what I'm doing. It would just generate lua code which could be linked into your flowgraph system then.

Link to comment

I'll shift my flowgraph design I currently have to be more "actor" oriented where you have an Update and Start method by default but allows you to create other methods and that's where you put your LE specific Lua code (visually of course) and it generates an "actor" script. That "actor" script could then be used in your flowgraph to make the connections.

 

I'll use your above example as a proof of concept and see what I can get.

 

What you have above still seems kind of not global, like your first Lua implementation before you made it so other objects could see each other. The way you have, for example, the movement variable seems global to the Lua state and not to this script, so if anything else used movement it could screw it up. Do you know yet how you are going to handle that? It would seem this script itself would need to be it's own class (table) definition in Lua, so you can have variables that aren't global but local to the class.

Link to comment

This is great direction guys .

 

@Rick

 

The best example for visual programming is editor in Massive Brain Software by Weta Digital it is really powerful. They have few simple nodes like: if, input, output, logical nodes: AND, OR etc. With them you can make advance behaviors and save like behavior. Once, when you have those behaviors you can use them in your programs.

 

For Example there is just one input node, there is command field in it. By command you can specify what input you want. You can have input from the terrain. That input will output terrain height on that position and normals, or Vision input, voice input etc..

 

In our case we can have input event like: LevelLoaded, onUpdate, terrain input etc.

 

Also some thinks like in UDC Kismet: Vars, IF Else, Switch - Case, Trigger, etc sound nodes.

 

This is great direction , I had plans for something similar , i really want to help you , ports for BlitzMax or anything .

 

but that doesn't need to be your system. I think that would fit into what I'm doing.

[/Quote]

 

That is great idea ,we can fast have a lot of useful staff , if we work together .

 

EDIT:

@Rick

Could you please think about portability

Blitzmax is great for editors and tools design ,I am working on Cut scene editor for my project . Can fit easy in your project something like Matinee in UDK it will be really useful .

Link to comment

Sorry, was referring to Josh's script he posted above which had some undefined thing to it yet.

 

@Afke

I'm all on board with the if's, switches, etc. That will all be there. About LevelLoaded, OnUpdate and such, that is more higher level than I'm thinking currently. With the tool I'm building you would be able to create those yourself from the more lower level LE commands.

 

Now with hearing how Josh is planning on Lua for LE 3 I think it'll shift into using flowgraphs to generate these actor scripts that you can then attach to entities and then link them via Josh's flowgraph. So for example the script Josh has above could be created in my flowgraph system visually instead of having to know Lua. My flowgraph system goal was always to be LE oriented and if this is the direction Josh is taking for LE 3, I'd really like to get an early jump on helping people make these actor scripts visually. Once you've created an actor script via my flowgraph, you can then use the LE flowgraph to make the links between other actor scripts. I think even programmers could benefit from this because you don't have to worry about the Lua syntax, but instead more focus on the logic you want to create.

 

I was asking if Josh had a more final version of how he wants these actor scripts though so I can actually start with the Lua code generation now.

Link to comment

About LevelLoaded, OnUpdate and such, that is more higher level than I'm thinking currently. With the tool I'm building you would be able to create those yourself from the more lower level LE commands.

 

It is just exactly what I'm talking about, It will be more powerful.

 

LE3 Josh's direction is great in my opinion, and you are right, everithin has to be LE oriented :)

Link to comment

"but I think without a visual display of everything you have access to, it's not much fun."

 

this is the ultimate reason why programming and me don't mix...not enough immediate visual feedback

as to what changes mean in getting at the end-result I'm seeking.

 

So the bottom line for me personally is: Bring on the Flowgraphs! (and the power to tinker with their

internal properties and observe how the objects they are attached to get affected in realtime)

:)

Link to comment
Guest
Add a comment...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...