chrismaltby / gb-studio

A quick and easy to use drag and drop retro game creator for your favourite handheld video game system
https://www.gbstudio.dev
MIT License
8.52k stars 470 forks source link

Custom JS Scripts #31

Closed mrcampbell closed 1 month ago

mrcampbell commented 5 years ago

First off, this is incredible! I love how you abstracted the details of making a game so that a non-developer can use it. I've shared it with the people in my company (sales and all) in an attempt to help get them involved in code.

I don't distract from the "Scratch" component, but what would it take to add a "Custom Code" segment where an API call could be made? I'm asking because, if it's a good idea and/or possible, I'd like to help.

I do Vue, Angular, Node and Go, and so I could be of assistance.

fuzzymannerz commented 5 years ago

Would love for a way to edit and tweak the code about before build to refine the game a bit more and an API that taps into that gets a vote from me for sure!

HeyItsLollie commented 5 years ago

I'd very much love to be able to add my own "event" scripts -- maybe even full script access to GB Studio's built-in events, so that I can clone and tweak the behavior of certain scripts when needed.

This is maybe only partially-related, but as an example: One of my favorite game-development tools is Hutong Games' PlayMaker for Unity, a complete visual-scripting solution for state machines. Every single action provided by PlayMaker is a tiny C# script, so if you need an existing action to behave differently for whatever reason, you can just copy its script, make your changes to it, give it a new name, and then that action is available to use.

Because each of PlayMaker's actions are just C# scripts, an entire community has grown around PlayMaker for creating and distributing new Action packs, along with helping other users figure out solutions for how to combine certain actions to create larger events. I figure a similar approach would be greatly beneficial to GB Studio in the long run: Opening up script access would effectively help offset the workload required to create more events for users, allowing @chrismaltby to focus more on the program and the engine itself, and he can build a strong community around GB Studio in the process.

clsource commented 5 years ago

I believe this can be achieved by using c files with just 1 function in them.

void my_custom_script(void *state) {
   // my state changing function
}

The workflow could be the following

chrismaltby commented 5 years ago

I like this idea and I think the method that @clsource suggests could work quite well. I guess the problem is that the commands don't map cleanly to one function so take CameraMoveTo for example

This is the function that gets called when the event fires

void Script_CameraMoveTo_b()
{
  camera_dest.x = script_cmd_args[0] << 3;
  camera_dest.y = 0; // @wtf-but-needed
  camera_dest.y = script_cmd_args[1] << 3;
  camera_settings = (UBYTE)script_cmd_args[2] & ~CAMERA_LOCK_FLAG;
  camera_speed = (UBYTE)script_cmd_args[2] & CAMERA_SPEED_MASK;
  script_ptr += 1 + script_cmd_args_len;
  script_action_complete = FALSE;
}

Forget for a second the wtf comment, because the C compiler used is currently quite buggy and requires things like this from time to time (there's another issue about moving to a newer version of GBDK which hopefully will help). But the actual command is only setting the camera destination value, the actual work is done by void SceneUpdateCamera_b() and then UBYTE SceneCameraAtDest_b() is called from UBYTE ScriptLastFnComplete() to determine when the event is finished and the next one can fire. Either we could provide a list of defined interactions that the commands could do or you'd probably end up having to overwrite a bunch of places in the engine to do anything useful.

The other option I'd considered is adding an "Eject Engine" button on the build screen that would add an engine folder to your project, if present the app will use your local version over the inbuilt one allowing you to make any change you want to the code and providing a path for more advanced projects for those who want it. If you combine this with the json plugins definition that you suggested then you could add new events to the UI, then you need to code up the handlers for these in your custom engine. If you ever broke your custom engine you could just eject again causing it to replace the engine with the latest working version.

clsource commented 5 years ago

Yeah an engine selector could improve a lot in the current flow. You can have an engine tailored for RPG or platform, puzzle or visual novel or even demoscene like music games.

The engine just would consist c, asm files and supporting tools and a single json that will help the editor know wich events, actions, properties and other configurations are possible.

The idea is to standarize the engine directory and maybe have a single packages.json file that could trigger npm commands used in the editor. With this layout then anyone could fine tune the engine to their needs.

Maybe something similar to this

engines/
   default/
      tools/
          packages.json
          tool1.js
          build.js
       makefile
       code.c
       anothercode.h
       morecode.asm
       engine.json

    visualnovel/
       tools/
          packages.json
          tool1.js
          build.js
          index.js
       makefile
       code.c
       anothercode.h
       morecode.asm
       engine.json

Each engine could have its own set of tools and rules and they will be independent from each other. So if you would like to use GBDK, RGBDS or ZGB as the core it will not matter to the editor. The only that would matter to the editor is the engine.json file that defines the rules of each engine.