BSL:Manual: Difference between revisions

385 bytes added ,  11 December 2023
m
finished latest pass at wording
m (this sample code was always cursed; should be more logical now)
m (finished latest pass at wording)
Line 558: Line 558:


===Defining===
===Defining===
When beginning to define a function, you must begin the line with "func"...
When beginning to define a function, you must start the line with "func"...


  func int prepare_fight(int count, string enemy_name)
  func int prepare_fight(int count, string enemy_name)
Line 586: Line 586:


===Calling===
===Calling===
When you call a function it will execute its statements from top to bottom or until it hits a "[[#Returning|return]]" statement. This means that when you call a second function from inside another function, the second function will be executed until its end and then the rest of the first function will be executed.
When you call a function it will execute its statements from top to bottom or until it hits a "[[#Returning|return]]" statement. This means that when you call a second function from inside another function, the second function will be executed until its end and then the rest of the first function will be executed. You can think of the function calls as nested parentheses, where the innermost statement must close before the next-innermost level can close, and so on. (For example, here is a parenthetical statement (and another one (and one more!) inside of it)).


You do not use "func" when calling a function. You simply use its name:
You do not use "func" when calling a function. You simply use its name:
Line 605: Line 605:


===Recursive calling===
===Recursive calling===
A function can call itself, which is useful for various looping behavior, but a function can only call itself recursively up to about four times. Note that this limit is bypassed if you use "[[#fork|fork]]" to call a function from within itself, but this no longer counts as recursing because the logic will not complete in a predictable inside-to-outside order. For a non-recursive way to loop a function, see {{SectionLink||Looping}}.
A function can call itself, which is useful for various looping behavior, but a function can only call itself recursively up to about four times. Note that this limit is bypassed if you use "[[#fork|fork]]" to call a function from within itself, but this no longer counts as recursing because the logic will not complete in a predictable inside-to-outside order like our nested parentheses example earlier, but will instead run concurrently through all of the function calls. For a non-recursive way to loop a function, see {{SectionLink||Looping}}.


===Returning===
===Returning===
Line 631: Line 631:
...then it could be called this way in some other function:
...then it could be called this way in some other function:


  if (is_it_safe())
  if (is_it_safe() eq true)
     dprint("It is safe.");
     dprint("It is safe.");
  else
  else
Line 655: Line 655:


Note that calling the same function again before it finishes running the first time can have undesired effects. Using "sleep" before each call can prevent this overlapping execution. A short function like the example above should not need a "sleep" statement, as the remainder of the function after the "fork" call will complete in the same tick. But the more complex the function, the more ticks you will need to allow for it to complete, requiring "sleep(1);", "sleep(3);", etc. before the "fork" call.
Note that calling the same function again before it finishes running the first time can have undesired effects. Using "sleep" before each call can prevent this overlapping execution. A short function like the example above should not need a "sleep" statement, as the remainder of the function after the "fork" call will complete in the same tick. But the more complex the function, the more ticks you will need to allow for it to complete, requiring "sleep(1);", "sleep(3);", etc. before the "fork" call.
An alternate looping method: Under "Concurrency" below are two variants of the "schedule" keyword. By scheduling a function call that operates on global variables and doesn't run unless a condition is true, you could simulate a slow-acting loop.


===Concurrency===
===Concurrency===
Line 681: Line 683:
  }
  }


As you can see, you can use forked functions to perform delayed actions without holding up the rest of the script; this not only allows the use of "sleep", but also any built-in functions that hold up BSL by design, like [[chr_wait_animation]].
As you can see, fork-called functions can delay actions within themselves without holding up the rest of the script; this not only allows the use of "sleep" without affecting outside functions, but also any built-in functions that hold up BSL by design, like [[chr_wait_animation]].
 
Also be aware that accidentally calling a nonexistent function using "fork" will crash Oni; when "fork" is not used, BSL will not recognize that the unknown function name represents a function, and thus will not attempt to call it and end up crashing.


Below are two types of uses for the "schedule" keyword. By scheduling a function call that operates on global variables and doesn't run unless a condition is true, you could simulate a slow-acting loop with these keyword sets.
Be aware that accidentally calling a nonexistent function using "fork" will crash Oni; when "fork" is not used, BSL will successfully recognize that it is an unknown function and thus will not attempt to call it.


====schedule ... at ...====
====schedule ... at ...====
Line 704: Line 704:
  schedule dprint("Is this annoying yet?") repeat 50 every 20;
  schedule dprint("Is this annoying yet?") repeat 50 every 20;


This is equivalent to the following loop in a C-style programming language:
This is equivalent to the following loop in a C-style language:


  int i = 0;
  int i = 0;
Line 718: Line 718:
  schedule dprint("Is this annoying yet?") repeat 0 every 20; # repeats forever
  schedule dprint("Is this annoying yet?") repeat 0 every 20; # repeats forever


"schedule-repeat-every" can be used in place of recursive functions that call themselves ''n'' times using "fork". For example,
"schedule-repeat-every" can be used in place of recursive functions that call themselves ''n'' times using "fork". For example…


  func void hey(void)
  func void hey(void)
Line 732: Line 732:
  }
  }


can be replaced by:
…can be replaced by…


  func void hey(void)
  func void hey(void)