• All, Gmail is currently rejecting messages from my host. I have a ticket in process, but it may take some time to resolve. Until further notice, do NOT use Gmail for your accounts. You will be unable to receive confirmations and two factor messages to login.

Documentation Project

O Ilusionista

Captain 80K
The Documentation Project - The mission to dig up things undocumented in OpenBOR.

The idea here is quite simple: To discover all the hidden things in OpenBOR.

This topic started on Plombo's To-do list after I saw many undocumented things. By CRxTRDude sugestion, I made a separated topic.

Since I started in OpenBOR, I keep finding things "hidden" or just undocumented. The reason for this happens can be multiple, but I don't care about it, since it won't help us at all. But undocumented things affects the community as a whole, because stop us to do what we want to.

After I took a look on a list made by Plombo, here is evertyhing I found. There are things with superficial documentantion, things with documentation only in Wikia ( I will add it to the manual as well) and things with no documentation at all.

Almost every aiflag has no documentantion. For example, "Animating" is when the entity is finished the fall animation (took from a DC's post). But "falling" triggers when the entity is falling, on the air?

To keep the topic clean, I will give you the Pastebin: link http://pastebin.com/dvNPcgqv
Its a long list, I know. But if you (or any other OpenBOR coders) could take a look in any of the options, I would be glad to add to the manual.

So, I would like to invite EVERYONE to try to solve those mysteries. Specially any of OpenBor coders like DC, Plombo, uTunnels, CRxTRDude, etc And people skilled with scripts, like White Dragon, Bloodbane, bWWd...

Thanks.
 
Okay, there are of course needs to have ground rules here.

FIRST AND FOREMOST, THEY NEED TO BE TESTED AND VERIFIED before only then can Illusionista add it on the manual and/or wiki. I'll help with adding what revisions they started from. Usually the coders like utunnels added comments in their commits which gives clues and hints. This was what I did and TortoiseSVN became such a weapon for such. And of course board rules still follow.  :)

Back to regularly scheduled programming.  ;)

For starters:

The GIF animation script commands
Basic:
Code:
playgif (path, x, y, noskip)
  • Plays animated GIFs. Specifically calling OpenBOR's animated gif player (via a similarly named command) to play a gif, much like
    Code:
    animation
    in a scene file.
  • commands are similar to animation, path for the file, x and y for the placement and noskip is to prevent skipping.

Advanced:
Code:
openanigif(path)
  • Apparently, opens an animated gif and returns it as a handle.
  • Purportedly be defined as:
    Code:
    nikki = openanigif("data\scenes\nikki.gif");
    . Nikki will become a variable for the other commands to be used.

Code:
decodeanigif(gif)
  • 'Decodes' an animated gif handle, which can be used to start and freeze frames.
  • e.g. using the example above:
    Code:
    decodeanigif(nikki);

Code:
getanigifinfo(gif, varname)
  • Gets information about the animated gif handle.
  • Example:
    Code:
    getanigifinfo(nikki, "width");
    would return the width of the GIF file.

Accepted values for getanigifinfo:
  • buffer - displays the buffer of the GIF
  • done - variable if the gif's finished playing
  • frame - the current frame the GIF is in
  • isRGB - color info? (possibly the 16bit thing that utunnels said that you can use on gifs, but that's disputable)
  • width - width of GIF
  • height - height of GIF
  • nextframe - the next frame of the GIF?
  • lastdelay - the delay of the individual frame, since it's an animated GIF. But from the name though, it seems that it's for the delay of the previous frame.

Description:
Started by utunnels in revision 3873
Remove old aicheck*** script functions. New script functions openanigif, decodeanigif and getanigifinfo.
Tested: NO on some. playgif works, as seen in some mods with custom menus derived from utunnels code. (Examples are Skull Kingz' The Burning Fox and White Dragon's TMNT mod)



Code:
fontmbs {font1}{font2}{font3}{font4}{font5}{font6}{font7}{font8}

  • Similar to fontmonospace, but this time adds multi-byte string support. For those who don't know, here's Wikipedia's article on such.
  • 0 disables it for the font and 1 enables it for the font.
Description:
Started by utunnels in revision 3624
Multi-byte string support for font functions.
Add a new command fontmbs in menu.txt to flag this change.

Tested: Recently spotted in RV2 2.4 by Volcanic for the purpose of adding Chinese characters, but nobody since has utilized it.

More info:
I have recently spotted something related to this in a Chinese BBS forum searching at Google.

Rough translation of something I saw there:
Run "OpenBor Chinese character generation tools."
Apparently, Volcanic (or someone else) made a tool that exploits this. Needs more data.



Code:
loadsprite(path, [i]maskpath[/i])
  • Similar to the original one except that it includes another parameter for a mask.
  • How to use it, probably just add the image and the mask, probably the same size (the mask's dominant color should be the first color index like gifs) and now it loads it. You would then need to call it over and show it to the screen I think.

Description:
uTunnels added the second parameter, 'maskpath', in revision 3968.
loadsprite now allows alpha mask.
Tested: EDIT: Tested by SimonSmith, did not work as intended. Needs more data and a mod that uses it.

Long thread, but since, I have not enough sleep, I'm gonna sleep for now.
 
I'll help wherever I can - this is one of those things I want to do myself but just haven't had the time to sink my teeth into. It's almost astounding some of the things OpenBOR can do that we don't even know about. Thank Utunnels for a lot of that - he was a machine when it came to working on the engine and I hope he comes back someday, but documentation wasn't his thing, lol.

DC
 
Great initiative!
This way more and more features can be found!

Something I experienced back in the days, when I realized the nex possibilities in Openbor compared to Bor!
 
Thanks everyone. Lets dig those things :)

About this:
For example, "Animating" is when the entity is finished the fall animation (took from a DC's post). But "falling" triggers when the entity is falling, on the air?

Any clue? And "animating" is not a good name for that :)

 
ok, a little at a time will write the documentation on the functions that I know.
I start with:

STRING FUNCTIONS:
strinfirst(STRING, SUBSTRING):
search the first match in a string.
params are complete string and substring to search in complete string.
it search SUBSTRING in STRING and if the substring is in string returns the substring, else it returns -1;
EXAMPLE:
strinfirst("HELLO", "LLO") returns LLO
strinfirst("HELLO", "HI") returns -1

strinlast(STRING, SUBSTRING):
like strinfirst() but returns the last substring match.
that is the func search in the string from right (not from left)

strleft(STRING, INDEX):
it returns a substring, the left part of a string from index 0 to INDEX.
EXAMPLE:
strleft("HELLO", 4) returns "HELL"

strright(STRING, INDEX):
like strleft() nut it return the right part from INDEX to END_OF_STRING

strlength(STRING):
it return the string length.
EXAMPLE:
strlength("HELLO") returns 5 (the string is length 5 characters)

strwidth(STRING):
it returns the string width in pixels depending by the font.
EXAMPLE:
strwidth("HELLO")
if the width of the character is 6 pixels and the string is "HELLO"
strwidth("HELLO") will returns 6x5 = 30 (30 pixels)
useful to align a string in the screen specially if you use multi-byte strings.

EXAMPLE of substr() and getchar():
Code:
char getchar(char str, int index) {

    if ( index >= strlength(str) ) index = strlength(str)-1;
    else if ( index < 0 ) index = 0;

    if ( strlength(str) > 0 ) {
        str = strright(str, index);

        if ( strlength(str) > 1 ) {
            index = 1;
            str = strleft(str, index);
        }
    } //else str = "";

    return str;
}

char substr(char str, int start_index, int length) {
    if ( start_index+length > strlength(str) ) return NULL();
    if ( start_index < 0 || strlength(str) <= 0 ) return NULL();

    str = strright(str, start_index);
    str = strleft(str, length);

    return str;
}

SCRIPT FUNCTIONS:
allocscript(name, comment):
it allocs a script in memory.
useful to compile a dynamic script on fly.
EXAMPLE:
allocscript("Script1", "this script is the 1st one")

loadscript(handle, path):
it loads a script in the handle created by allocscript() from the specified path.
EXAMPLE:
loadscript(script_handle, "data/scripts/script.c")

compilescript(handle):
it compile a script on fly

executescript(handle):
it executes a script.

EXAMPLE to load and execute a script:
Code:
void handle = allocscript("script1","any_comment");
loadscript(handle,"data/scripts/script.c");
compilescript(handle);
executescript(handle);

NOTE: if you want you can create a script file with filestream functions.
then you can load and execute your script on fly!

CUSTOM MENU FUNCTIONS:
loadgamefile(): reload saved level file from saves (example bor.sav)
getsaveinfo(set_index, prop): gets the info from *.sav file loaded by loadgamefile().
EXAMPLE:
if a game has 3 SETS (ex ARCADE, VERSUS, TRAINING), set_index will be 0 (ARCADE) or 1 (VERSUS) or 2 (TRAINING).
prop has these wildcards:
"flag": is there a slot in memory? if yes flag == 1 else 0.
"level"
"stage"
"times_completed"
"score"
"lives"
"credits"
"name"
"playername"
"health"
"mp"

getsaveinfo(0, "SCORE") returns the score in ARCADE set (if the set 0 is ARCADE for example) in the last playing.

playgame(set_index, usesave): set_index like getsaveinfo and usesave == 1 if you want continue your game from a loaded file, else use 2.
EXAMPLE:
playgame(0,1) to continue the ARCADE mode or playgame(0,2) to start an ARCADE mode.

options():
it shows options menu (control, video, etc..) for a custom menu.

shutdown():
it closes the engine.

ARRAY FUCTIONS:
array(size): create an array.
EXAMPLE:
int a = array(0);

get(array,index):
get an array element from index location.

set(array, index, value): set a value in array in index location.
size(array): array size (number of elements)
reset(array),next(array),key(array),value(array): for hash_array, I thinks they do not work properly.
free(array): free an array to free the memory. it's very important
when you finish to use an array you is a MUST to free an array.
EXAMPLE:
setlocalvar("array1",array(0));
... ...

void ondestroy() {
if ( getlocalvar("array1") ) { free(getlocalvar("array1")); setlocalvar("array1",NULL()); }
}

rgbcolor(value1,value2,value3):
the colors in computer are represented by 3 bytes in hexadecimal encoding (in form RGB).
ex. 0xFF0000 which is the color red. 0xFF is the red gradient R 0x00 is the green gradient G (empty) and the last 0x00 is the blue gradient B.
This is the RGB form.
some devices read the color from left to right and the others on the contrary.
for example the Wii reads 0xFF0000 as 0x0000FF that is blue instead.
To overcome these disadvantages of incompatibility is useful to use rgbcolor().
EXAMPLE:
good: changedrawmethod(NULL(), "tintcolor", rgbcolor(0xFF,0x00,0x00)); // red in anyway
incompatibility issues: changedrawmethod(NULL(), "tintcolor", 0xFF0000); // red on pc but blue on Wii
 
(I'm not an english native speaker so I'll just try to explain what I understood, which might not be "documentation ready" nor accurate for that matter.)

attackz {zMin} {zMax} : allow to set a more precise attack depth. With this you can make attack that will only hit enemies above or below self z position. In other words it changes the z "center" of the attackbox.
hitz {zMin} {zMax} : same as attackz

bboxz {zMin zMax} : same principle as attackz but with bbox. With this you can set a bbox that is wider above than below for exemple.

Note that unlike standard attack command, you can already set zMin & zMax bbox properties with the standard bbox command by adding a 6th parameter : (e.g. bbox x y width height zMin zMax)


subclass {model} : allow inheritance of a cached model. Don't know if it works but if it does this is awesome to create variations of the same character.

pfstep {val} : means path find step. if greater that 0, change the way in which path blocking is solved. Can't tell precesily how, but the higher the value, the higher the change.



aiattack {val} : define a.i. attack style for this entity. Accepted values : normal, always, noattack.
"normal" is just normal, default a.i. attack style.
"noattack" is as the name implies (default for some types of entity, such as obstacle IIRC)
"always" only bias the chance of initiating an attack to 1 (= always initiate attack)


_____

single {0/1} : if set to 1 has the same effect as setting maxplayers 1
 
.  subclass : allow inheritance of a cached model. Don't know if it works but if it does this awesome to create variations of the same character.

pfstep : means path find step. if greater that 0, change the way in which path blocking is solved. Can't tell precesily how, but the higher the value, the higher the change. 

From where you got this? And path of what?
 
@White Dragon, glad you're with us into this, and at least we got someone that might used one of these commands. Did you somehow one way or the other used them? Just curious, especially the menu ones.

@Piccolo, nice that you also participated as well. Problem now is that if the pathfinding needs more documentation as well.

Now for my thing, apparently last night I stumbled upon and searched for the Chinese Font tool that the one in my link was talking about. Apparently, either the link is down or i can't search for it enough. If one of you guys here at the forum reading this can understand Chinese and might want to search the tool that they talk about, it might be very helpful. If it has source, that might be also great and we can use that and investigate so that we can identify for sure if we can use other encodings.

Oh and one other thing, i think the rason why Volcanic actually had a lot of knolwdge regarding utunnels' edits is probably because utunnels is Chinese as well (some of you probably know) and might have posted some info on some Chinese BBS.
 
Piccolo said:

Notes:




subclass appeared probably in Rev 3228 by anallyst as a WIP feature for OOP, but I think it might not be as useful in our current situation. For that, we just have to wait for ChronoCrash instead.
WIP for a new feature, which should allow one to subclass a model like in OOP


Code:
pfstep's
first appearance is in Rev 3522 by utunnels (also includes the
Code:
waypoints
command as well):

Add a new model command pfstep (pathfindstep), when it is greater than 0 pathfinding is enabled. Smaller value means more accuracy, but the valid search area is also reduced. This property is also opened to script.

Add a new script function waypoints that allows way points setup.

In rev 3524, he added comments for the AI code apparently.



Code:
[i]aiattack[/i]
is originally an earlier endeavor. But the parameters probably were set up again by utunnels in rev 3676:

aiattack command now available.
aiattack normal (default).
aiattack noattack (do not attack even if you give attack animations)
aiattack always (more aggressive than normal, like old version



and single needs to be deprecated, apparently maxplayers does the job just as well as it.
 
Code:
waypoints(ent, x1, z1, x2, z2, x3, z3, ...)
  • Used to define waypoints that the enemy or NPC AI follow. On where it should go is the mystery to it, probably in the level.c where it would check on what level it's going over.
  • {ent} is the entity that would be affected.
  • Apparently, you can have as many waypoints as you can, I think. Two values are needed though the x and z. They are probably relative to the entity it's affected.
  • Another thing, "zero length list means clear waypoints". Meaning if you set the list as without the other parameters: eg.
    Code:
    waypoints(nikki);
    , this might clear the waypoints (probably useful if level is either finished or if you don't need it anymore).

Description:
Appeared in revision 3522 by utunnels (see previous post).

Tested: NO.



EDIT: removed pausemusic here, because I incorporate it with the other related functions that I found working.



Code:
shutdown(status, message, ...)

  • Provokes the engine to shut down completely. Can be a tool for debugging and error catching.
  • 'status' will depend how the game would shut down. 'message' is similar to printf, with the '...' as substitutions. Once the shutdown is complete, the message will be added to the log, perfect for debugging custom stuff.
  • Example is:
    Code:
    shutdown(1, "Error: unknown cached background '%s'", filename);

Accepted values for 'status':
0 - Just shuts down normally, in the log, it prints:
************ Shutting Down ************
1 - Shuts down, but in the log it says:
********** An Error Occurred **********
                      Shutting Down
2 - Shuts down with error but will not display the engine's credits. By default, both 0 and 1 displays the engine credits.

TESTED: NO, but might work.

More to come, I've arranged along with Illusionista to put the Pastebin text to the wiki instead so that we can see the progress of the code so far and here it is:
http://www.caskeys.com/arc/games/openbor/wiki/index.php?title=Documentation_Project

Please do take a look at the list for people who participate to this project. Thanks.  ;)

EDIT: I forgot that White Dragon already tackled shutdown, I just want to expound it though. Sorry. :-[
 
single {0/1} : if set to 1 has the same effect as setting maxplayers 1

I remember that single [bi] is used for only player 1. I think I did use it that was probably in the levels.txt before. I forgot about it till Piccolo pointed out. (I never mentioned it because I thought it was in the DCEmulation.)
 
BTW, Illu, I'm sorry that I actually joined DC Emu forums, I want to edit the Wiki there as well, but that's a bad move.  :-[

Anyway, I'll make it up and try to find the aiflags in the source. I'll place them in the Wiki when done.
 
I got another feature that I don't see anywhere in OpenBOR's manuals. The fact that you can make your own custom menu with some custom levels placed in front of data. This needs to be known at least, adding custom menus and stuff using levels.

If only people can help with this and place it step by step rather than ramming it into a sample game; not that there's something wrong with learning by yourself, but it's better if new people can at least go over this and know that people can do this and stuff.

Right now, I'm adopting Volcanic's story script method, which I got working displaying the dialog, but still working over the bugs.
 
Sound functions:

Code:
pausemusic (value)
  • Pauses the music abruptly. technically, it toggles the variable 'sound_pause_music', commonly used for the pause menu to stop the music while the pause menu is present.
  • 'value' can be 0 for playing and 1 for pausing.

Tested: YES



Code:
fademusic (fade, name, loop, offset)
  • With only fade as parameter, it fades the music in or out. Adding parameters, it will replace the current music.
  • {fade} values: 0 to fade in, 1 to fade out.
  • {offset} probably in seconds, sets where the the fade will start?
  • The rest are similar to playmusic.

Tested: For the one parameter, YES. For the rest of the parameters, NO, but might work.



Code:
setmusictempo(var)

  • Sets the tempo of the music. {var} is tempo, higher the value, higher the tempo and vice versa.

Tested: NO.



Code:
getgfxproperty(sprite,property)
  • Gets the property of a sprite or graphic displayable.
  • {sprite} should be a valid sprite defined with loadsprite.
  • {property} is the property of the sprite that you want to get.

So far, these are the sprites that were identified:
- "height" - the height of the sprite, probably with transparency on.
- "width" - the width of the sprite, probably with transparency on.

These were all the ones identified so far and will explore more.

TESTED: YES. Implemented in some mods including Rocket Viper 2.4
 
I was searching from stuff at LavaLit in the Wayback Machine for some documentation stuff and found this at the sig of one of the admins CE:

Did you know?
Using
Code:
void main()
{
playgif("data/my.gif", 0, -4, 1);
}
as spawnscript streams a GIF anim instead of loading it

Edited the layout of the script so that it would be understood well. Have anyone tried using playgif as such?

Oh yeah, that was from version 2 of OpenBOR, but I don't know if it still does such (the function is still there, but it's still something to test): Link courtesy of the Wayback Machine.
 
Back
Top Bottom