Ok, here is an example of controlling the ship in script from the host side.

host side:
[code=delphi]program pstudio_scripting;

{$APPTYPE CONSOLE}

uses
SysUtils,
PGSystem,
PGGraphics,
PGActor,
PGScript,
PGApplication;

type
{ --- TScript --------------------------------------------------------------- }
TScript = class(TPGScript)
protected
FLastModual: string;
public
constructor Create; override;
destructor Destroy; override;
procedure OnCompilerProgress; override;
end;

{ --- TShip ----------------------------------------------------------------- }
TShip = class(TPGEntity)
public
constructor Create; override;
destructor Destroy; override;
function NextFrame: Boolean; override;
procedure RotateRel(aAngle: Single); override;
procedure Thrust(aSpeed: Single); override;
end;

{ TShipUpdate }
TShipUpdate = procedure(aShip: TShip; aElapsedTime: Single);

{ --- TScript --------------------------------------------------------------- }
constructor TScript.Create;
begin
inherited;
FLastModual := '';
end;

destructor TScript.Destroy;
begin
inherited;
end;

procedure TScript.OnCompilerProgress;
begin
if FLastModual <> Self.GetCurrModuleName then
begin
FLastModual := Self.GetCurrModuleName;
WriteLn('Compiling ',FLastModual,'...');
end;
end;


{ --- TShip ----------------------------------------------------------------- }
constructor TShip.Create;
begin
inherited;
end;

destructor TShip.Destroy;
begin
inherited;
end;

function TShip.NextFrame: Boolean;
begin
inherited;
end;

procedure TShip.RotateRel(aAngle: Single);
begin
inherited;
end;

procedure TShip.Thrust(aSpeed: Single);
begin
inherited;
end;

var
Sprite: TPGSprite;
Page : Integer;
Group : Integer;
Ship : TShip;
Script: TScript;
Ship_Update: TShipUpdate;

{ --- Demo ------------------------------------------------------------------ }
function Demo_Init: Boolean;
var
i: Integer;
s: string;
begin
Result := False;

// init display device
PG.DisplayDevice.Open('pstudio - Scripting', dm800x600, True, True);

// init render device
PG.RenderDevice.SetMode(0, seDiscard);

// init sprite object
Sprite := TPGSprite.Create;

// load ship texture
Page := Sprite.LoadPageFromFile('ship.png', PG_ColorKey);

// add ship group
Group := Sprite.AddGroup;

// add images to ship group
Sprite.AddImageFromGrid(Page, Group, 0, 1, 64, 64);
Sprite.AddImageFromGrid(Page, Group, 1, 1, 64, 64);
Sprite.AddImageFromGrid(Page, Group, 2, 1, 64, 64);

// init ship entity
Ship := TShip.Create;
Ship.Init(Sprite, Group);
Ship.FrameFPS := 14;
Ship.SetPosAbsXY(400, 300);

// init script manager
Script := TScript.Create;

// register TShip class type
i := Script.RegisterClassType(0, TShip);

// register TShip methods
Script.RegisterHeader(i, 'constructor Create; override;', @TShip.Create);
Script.RegisterHeader(i, 'destructor Destroy; override;', @TShip.Destroy);
Script.RegisterHeader(i, 'function NextFrame: Boolean; override;', @TShip.NextFrame);
Script.RegisterHeader(i, 'procedure RotateRel(aAngle: Single); override;', @TShip.RotateRel);
Script.RegisterHeader(i, 'procedure Thrust(aSpeed: Single); override;', @TShip.Thrust);

// add a new pascal module
Script.AddModule('ship_logic', lsPascal);

// add source into pascal module
Script.AddCodeFromFile('ship_logic', 'ship_logic.pas');

// compile the script
if Script.Compile then
begin
// get the address of update routine
Ship_Update := Script.GetAddress('Ship_Update');

// check if valied
if not Assigned(Ship_Update) then
begin
PG.ShowMessage('debug', 'Failed to get routine address', &#91;]);
Exit;
end;
end
else
begin
// display errors
for i := 0 to Script.GetErrorCount - 1 do
begin
s := Format('%s(%d:%d):%s', [Script.GetErrorModuleName(i),
Script.GetErrorLineNumber(i) + 1, Script.GetErrorLinePos(i) + 1,
Script.GetErrorMessage(i)]);
WriteLn(s);
end;
PG.ConPause('Press ENTER to continue...');
Exit;
end;

Result := True;
end;

procedure Demo_Done;
begin
// destroy script
PG_FreeAndNil(Script);

// destroy sprite
PG_FreeAndNil(Sprite);

// restore desktop mode
PG.RenderDevice.RestoreMode;

// close display device
PG.DisplayDevice.Close;
end;

procedure Demo_Update(aElapedTime: Single);
begin
// update ship via script
Ship_Update(Ship, aElapedTime);
end;

procedure Demo_Render;
begin
// render ship
Ship.Render(0, 0);
end;

procedure Demo_Run;
begin
// game loop
while not PG.Terminated do
begin
// process windows messages
PG.ProcessMessages;

// check if the render device is ready, loop if not
if not PG.RenderDevice.Ready then
begin
continue;
end;

// update timing
PG.Timer.Update;

// update demo
Demo_Update(PG.Timer.ElapsedTime);

// clear frame buffer
PG.RenderDevice.ClearFrame(cfDefault, PG_SkyBlue);

// start frame
if PG.RenderDevice.StartFrame then
begin
// render demo
Demo_Render;

// end frame
PG.RenderDevice.EndFrame;
end;

// show frame buffer
PG.RenderDevice.ShowFrame;
end;
end;

{ --- Main ------------------------------------------------------------------ }
var
ok: Boolean;
begin
// init demo
ok := Demo_Init;
try

// if all ok run demo
if ok then
begin
Demo_Run;
end;
finally

// shut down demo
Demo_Done;
end;
end.[/code]

script side:
[code=pascal]
// update native TShip from compiled script
procedure Ship_Update(aShip: TShip; aElapedTime: Single);
begin
// update next frame
aShip.NextFrame;

// rotate to new angle
aShip.RotateRel(3.0*aElapedTime);

// thrust in the direction of rotate
aShip.Thrust(7.0*aElapedTime);
end;

begin
end.[/code]

You can download the Delphi project here.

Comments:[*]Even though TPGEntity is already registered by the scripting system, because TObject is crossing the DLL boundary you will still need to registered all methods and routines that you want "seen" by the scripting system from the host side.[*]Once the script is compiled, you can use GetAddress to get the address of a script object (variable, routine, method)[*]If you wanted to access a class on the script side you would simply call CreateObject, GetAddress to get it's address, and finally call DestroyObject to destroy the class.[*]Note it really does not matter which direction you take because the compiled script is x86 native code. On average it will be about 3 times slower than optimized Delphi code.[*]All the examples from the pascal folder are standalone compile versions which shows just how fast the scripting system really is.[*]Scripts can be compiled and save out to a DLM (Dynamic Loadable Module). You can then load this in at run-time to access your routines and classes.[*]The whole SDK is already registered so from script you have access to PGE and can do almost anything in script, including loading in other DLMs and having the running script access that.