November 15, 2019, 08:58:58 AM

Author Topic: Post-Compilation Dynamic script events  (Read 174 times)

Offline _PJ_

  • Jr. Member
  • **
  • Posts: 32
Post-Compilation Dynamic script events
« on: October 24, 2019, 07:31:14 PM »
I see that BMax features LUA and wonder if this is possible and suitable.

I am hoping to implement dynamic, randomly accessed script events and am unsure of how best to approach this.

I hope I can explain this clearly enough...


Imagine a game includes various classes of in-game 'physical' objects. These objects' properties in the 'game world' are individually defined from template resource assets. These can be loaded dynamically. All normal, standard asset faire so far, right...
HOWEVER, interactions (through gameplay) with these objects is determined according to - at least in my intention - certain event scripts. The paricular script to be called is itself referred in the file asset for that template.

A pseudo-example of how such a template may look is:

OBJECT_TYPE=Button
OBJECT_NAME=Button1
OBJECT_ACTION=Push
EVENT_ONACTION="pushbutton.script"

Of course, the compiler is not going to have any way to interpret and compile "pushbutton.script" with any relation to whatever 'object' (as class object here) is generated in memory when that particualr template is loaded.

I am unsure how to approach this, but have thought about some kind of "pre-compilation" of all possible such scripts (even though it's not known if any are actually going to be used - if no template that contains a reference to a script is ever loaded to generate an object, that script will never be called for example) - and then when the gameplay processes actually require to call the necessary script function (i.e. when the BUTTON object in example is 'pushed' within the mechanics of gameplay) then the relevant compiled script is somehow referenced instead and called accordingly...

Is this a good approach? What alternatives might there be? Any advice, suggestions or otherwise relevant information is welcome.

I have toyed also with the possibility for having BMax code generated in the "script compilation", and then a full compilation of the entire application - protecting the core functionality of the language somewhat by encoding it under a particular packing algorithm whereby it will be secretly unpacked for the ACTUAL compilation which would necessitate bundling the relevant elements of BlitzMax (compiler & interpreter etc.) - For which I am unsure of what is absolutely minimum essential required for such.




Offline Derron

  • Hero Member
  • *****
  • Posts: 2569
Re: Post-Compilation Dynamic script events
« Reply #1 on: October 24, 2019, 07:59:42 PM »
Do as you did in your template

Code: [Select]
Type TButton
 Field name:string
 Field action:TAction = ACTION_PUSH
 Field _onAction:func(sender:TButton)
 Field _onActionScript:String
 Field _onActionScriptFile:String
End Type

Function MyOnAction(sender:TButton)
 Print "Button onaction : " + sender.name
EnD Function

local b1:TButton = new TButton
local b2:TButton = new TButton
b1._onAction = MyOnAction 'no brackets - so it is a pointer to the function!
b2._onActionScript = "my script code"
b2._onActionScriptFile = "myluafile.lua"

Of course you need to handle the lua file execution on your own (see how brl.MaxLua does do it). Same for your script code (you need your own script evaluator ...). The function pointer is useful if you have custom code you write in BlitzMax without the "TButton"-file having to know about the objects used in the function. But it is code compiled together with your other game code - not "precompiled" or so.
To have it truly customizable (aka you give the .exe and someone can alter the script file without recompiling the .exe) you need your own scripting language, a lua script - or .DLL/.so files (someone compiles a library which you then use).


bye
Ron

Offline _PJ_

  • Jr. Member
  • **
  • Posts: 32
Re: Post-Compilation Dynamic script events
« Reply #2 on: October 25, 2019, 06:14:58 PM »
Hi Derron, Thanks for the really fast resposne.

you need your own scripting language, a lua script - or .DLL/.so files (someone compiles a library which you then use).
This is the crux of the matter for me.

So it sounds like it should be possible to have externally compiled Lua scripts that are executed from within the running BMax code. Those scripts should be taking advantage of function and var pointers to interact fully with the requirements of the BMax code.

This is why I hoped that Lua can be used because there exists the MaxLua and it's a popular enough scripting language.
Of course, the power andpotential of what is possible via those scripts would be determined by what function and var pointers I can prepare within the BMax codebase itself, but this seems to be the best option, compared to attempting my own scripting language which would be very limited as it would also entail writing my own compiler otherwise, the result would simply be a slow, runtime interpretation and "translation of script function".


Offline Derron

  • Hero Member
  • *****
  • Posts: 2569
Re: Post-Compilation Dynamic script events
« Reply #3 on: October 25, 2019, 07:12:08 PM »
your own "scripting language" would not need a compiler - just an interpreter :)

Lua: You need to expose functionality / helper classes to lua - the lua scripts could then call these functions.

helper classes: I mean something like

Code: [Select]
Type TLuaFunctions
  Function MyClick:int()
  End Function

  Function ExecuteFunctionXYZ:int()
     game.ExecuteFunctionXYZ()
  End Function
End Type

But if the button-click-event mostly consists of one of a handful candidates "GivePlayerItem(swordID)" or so, then you might better have some simple string interpreter:
OnClickString = "GivePlayerItem,23"
Then split your string - compare the first one and handle accordingly

Code: [Select]
Select OnClickStringFirstPart.ToLower()
  case "giveplayeritem"
     GivePlayerItem( int(secondPart) )
  case "sellinventoryitem"
     SellInventoryItem( int(secondPart) )
'...
End Select

Next to strings you can also use predefined numbers (constants)
GIVEPLAYERITEM:int = 1
SELLINVENTORYITEM:int = 2
...
as comparisons of numbers is less cpu and memory manager hungry.


bye
Ron

Offline _PJ_

  • Jr. Member
  • **
  • Posts: 32
Re: Post-Compilation Dynamic script events
« Reply #4 on: October 25, 2019, 07:29:24 PM »

Lua: You need to expose functionality / helper classes to lua - the lua scripts could then call these functions.

helper classes: I mean something like

Code: [Select]
Type TLuaFunctions
  Function MyClick:int()
  End Function

  Function ExecuteFunctionXYZ:int()
     game.ExecuteFunctionXYZ()
  End Function
End Type

Well that's just amazing. It's so much simpler than I'd anticipated! Still not to be underestimated though, but you've really helped and given me a lot of confidence about tackling this! Thank you kindly!

It really wwould necessitate more than a basic interpreter, since the intention (despite my button example) would be more complex than a "If this do that" kind of singular function. Parsing the strings would be cumbersome I think.

The intention might be something more like (pseudoscript)

[Complex button push script]
cl_Object thisObject = GetSelfObject();

if ((GetObjectType(cl_Object))=BUTTON_TYPE_CONSTANT){
if (GetButtonState(cl_Object)!=TRUE){
  cl_Effect=GetParticleEffect(1234);
  SpawnParticleEffect(cl_Effect);
  SetButtonState(cl_Object,TRUE);
}
}

Which despite its apparent simiplicity already calls into a slew of classes and methods that would be required. But...yeah - you get the idea and the capacity for Lua to directly "utilise" the helper functions is extremely powerful and just what I need!





Offline Derron

  • Hero Member
  • *****
  • Posts: 2569
Re: Post-Compilation Dynamic script events
« Reply #5 on: October 25, 2019, 08:31:16 PM »
Your script would become way easier if you registered the script when knowing what button it is

SpawnParticlesButton.OnClickScript = ...
---
SpawnParticleEffect,1234
---

Your blitzmax logic would then split into "SpawnParticleEffect" and "1234"
It could then call
Code: [Select]
  local cl_Effect:TEffect = GetParticleEffect(thatID)
  SpawnParticleEffect(cl_Effect)

And if you needed more configuration you could always add more ",value,value" which you would tackle within BlitzMax.


But yes - I would prefer to use "lua" or another scripting language. Then I would expose all "possible" functions (maybe create them just for that purpose - so you create a kind of "API" to have defined points of access for the scripts and only a single file instead of having a dozen of exposed functions across dozens of bmx files).


bye
Ron

Offline _PJ_

  • Jr. Member
  • **
  • Posts: 32
Re: Post-Compilation Dynamic script events
« Reply #6 on: October 25, 2019, 08:58:55 PM »
But yes - I would prefer to use "lua" or another scripting language. Then I would expose all "possible" functions (maybe create them just for that purpose - so you create a kind of "API" to have defined points of access for the scripts and only a single file instead of having a dozen of exposed functions across dozens of bmx files).
This is the general intent I think.

There would be a generality of object and interactivity which would (hopefully) be more determined by the Lua, but this will need a wealth of "infrastructure" inplace within the BMax to facilitate the relationships between the BMax and the Lua references etc.

My initial post was because I wasn't sure if this was possible with BlitzMax's integration with Lua, but now that you've shown me that it is and in a far more direct way thatn I initially thought, it's really galvanised me in this direction. Much appreciated!

Offline Derron

  • Hero Member
  • *****
  • Posts: 2569
Re: Post-Compilation Dynamic script events
« Reply #7 on: October 25, 2019, 09:10:48 PM »
I use Lua to code my game's AI.

the game calls lua script functions - and these functions are enabled to call certain exposed Lua functions. Just check the "MaxLua"-examples - is pretty straight forward then.


bye
Ron