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.55k stars 470 forks source link

GetVariableValue Helper #720

Open bradybothwell opened 3 years ago

bradybothwell commented 3 years ago

Description: I'm working on a plugin right now to allow switching from one scene to another randomly or pseudo randomly, i want to build an entry for the 7 day roguelike using gb studio as the game boy is my favorite and there aren't enough games like cave noire.

the level switching seems to be working fine, basically I want to have a variable integer input (random or otherwise) select the next scene to load. the scenes are assigned slots by the user then i want to use a startup script to build the map.

the problem is if i try to pull, say input.variable.value, it breaks the script, and the compiler error really doesnt give me anything to work off of. This happens if I allocate a tmp as well, not sure if its a typecasting thing but i wouldnt know from the error message.

Example of desired function: user triggers exit event -> script determines next room number -> launches next stage from pool of stages selected for the exit

Solution: fairly straightforward, I need an easy way to pull the integer data out of a variable. I realize the plugin engine isnt going to be used by everyone but it adds a ton of flexibility and makes a 7drl entry possible

Alternatives: I've considered doing a massive switch statement but this is an attempt to minimize tons of objects in the inspector. Main alternative is to create a script that handles the entire random generation sequence at the beginning of the game and assign all levels as variables, then try to use the compare function to build the map network. Another option would be to demark a set of global variables representing the possible slot values at init, then compare based on those.

Context: I'm attempting to make this a modular set of controlled randomization tools, hopefully if the plugin engine is sticking around some other folks can get some use out of it too once I've got it acting right. I've attached my event plugin .js, its usable for fully random changes between 3 rooms atm (expandable if you know where to copy/paste)

TLDR i got random room jumping working, how to i get a variable number value as int to compare with a "number", also i probably need to learn more JS

I'm running the v2 beta for the record.

Thank you for this tool, you're making some boyhood dreams come true.

export const id = "SWITCH_SCENE_INDEX";
export const name = "Scene: Switch To Scene By Index";
export const fields = [
  { //this is supposed to set the key variable value that selects the next stage
    key: "sn",
    label: "Scene Select",
    type: "variable",
    defaultValue: "LAST_VARIABLE"
  },
  {
    key: "s0",
    label: "Scene Index 0",
    type: "scene",
    defaultValue: "LAST_SCENE"
  },
  {
    key: "s1",
    label: "Scene Index 1",
    type: "scene",
    defaultValue: "LAST_SCENE"
  },
  {
    key: "s2",
    label: "Scene Index 2",
    type: "scene",
    defaultValue: "LAST_SCENE"
  },
  {
    key: "x",
    label: "FIELD_X",
    type: "number",
    min: 0,
    max: 255,
    defaultValue: 0,
    width: "50%"
  },
  {
    key: "y",
    label: "FIELD_Y",
    type: "number",
    min: 0,
    max: 255,
    defaultValue: 0,
    width: "50%"
  },
  {
    key: "direction",
    label: "FIELD_DIRECTION",
    type: "direction",
    width: "50%",
    defaultValue: ""
  },
  {
    key: "fadeSpeed",
    label: "FIELD_FADE_SPEED",
    type: "fadeSpeed",
    defaultValue: "2",
    width: "50%"
  }
];

export const compile = (input, helpers) => {
  const { caseVariableValue, ifVariableValue , variableCopy, sceneSwitch } = helpers;
//  const tmp1 = "tmp1";      //non working, for reference
//  variableCopy(tmp1, input.sn);
//  if (tmp1.value == 1){ 
//    sceneSwitch(input.s1,input.x,input.y,input.direction,input.fadeSpeed);
// }

// Comparing values always returns as true, it just triggers whichever command comes first even if nested within eachothers default actions
// ifVariableValue(parseInt(input.sn.value), "==", 0,sceneSwitch(input.s0,input.x,input.y,input.direction,input.fadeSpeed),[]);
// ifVariableValue(parseInt(input.sn.value), "==", 1,sceneSwitch(input.s1,input.x,input.y,input.direction,input.fadeSpeed),[]);
// ifVariableValue(parseInt(input.sn.value), "==", 2,sceneSwitch(input.s2,input.x,input.y,input.direction,input.fadeSpeed),[]);

    const randSelect = Math.floor(Math.random() * Math.floor(3));
    switch (randSelect){
        case 0:
            sceneSwitch(input.s0,input.x,input.y,input.direction,input.fadeSpeed);
            break;
        case 1:
            sceneSwitch(input.s1,input.x,input.y,input.direction,input.fadeSpeed);
            break;
        case 2:
            sceneSwitch(input.s2,input.x,input.y,input.direction,input.fadeSpeed);
            break;
    }
};

``

RichardULZ commented 3 years ago

V2beta as in 2.0beta5? Plugins do not actually run JavaScript on the gameboy, they just let you access and compile the script command functions as part of scriptrunner_b.c. JavaScript math is only to help pick things in the editor outside of runtime.

A large switch event is probably your best option, perhaps a blank scene that handles the random selection, so you only have to script the scene selector once.

There's a few updates to the engine being tested in #709 , one in particular tries to improve random seed so it's not reseeded each script, but instead once on first button press (each call then increments the seed).

I'd also recommend a buffer of variables to store the last random scene picked, Set L3=L2, set L2=L1, set L1=L0, Define rand start Math rand L0, If L0==L1, Goto rand start Else if L0==L2, Goto rand start etc...

Then switch case based on L0 for the scene.

Also check out the discord for scripting help.

bradybothwell commented 3 years ago

I know theres translation going on, but i'm usually a C# coder so i wondered if i was missing something basic about access permissions or typecasting. i can see examples of the value being pulled elsewhere but i think it may be comparing it with another whole variable instead of trying to compare an int against a single param.

I'm on the last beta release from itch so 2.0b4,

I intend to have a cycle at init that creates a hacky 2D array from global vars, and use it to randomly lay out a map at the beginning using a ruleset to select the stages. When the user exits a room, an event checks the matrix for the assignment in that direction, and loads it. Should hit up the discord.