The library functions are Lua functions I have created and they are used by the scripts which are distributed with U61.
Basically, you could create your own set of rules from scratch, by filling user callbacks with pure calls to the core API. I honestly think it's too bad not to re-use some of the work I've already done. So a more reasonnable approach would be, in my opinion, to take an existing script and modify it until it fits your need. And this section's goal is to provide a documentation on what I have programmed my own scripts.
Basically, this section has 2 goals:
- Give an overview of what alreayd exists, and where to find it. For instance, if you want to modify a curse in the "classic" set of rules, you might find here in which file this curse is coded, and what resources it uses.
- Set up some coding guidelines. Of course since U61 is GPL'ed, you can modify the code the way you want. However, experience shows that no project can survive without a minimum of rules. Most of the rules I usein scripting for U61 are based on common sense and should not surprise anyone.
If you look in the source package, you'll find 2 subdirectories: "library" and "package":
- "library" contains most of the code, which is split in several modules, each ".lua" file being one of these modules.
- "package" defines the user callbacks. Each package requires functions from the library. The idea is that you can create multiples packages which rely on the same library modules. This way, when a library module gets some bug-fix or improvement, all the packages that uses it can benefit from the update.
If you code new scripts for U61, and want them included in the main U61 release, I'd really appreciate that you respect some basic rules, which should make the code easier to maintain. This is not to forbid you anything and should not endanger your freedom (remember the game is GPL'ed) but without a minimum of organization, I'm pretty sure it will be impossible to maintain an important database of scripts. And I'd just love it if zillions of Lua scripts for U61 could be available on the net.
I never build complete U61 rules within a single file. The method I use is to create many little files and then cat them together. Of course if you are trying new features, it might be usefull to take an existing script, for instance "classic.lua", and edit it directly. And if you want to share this script with other people, you can put it on ftp for download without even asking me. BTW, if you do that, a good idea would be to rename the script. Indeed, in a network game, clients can automatically save the server script on their hard drive, and they might get confused if there are 33 different "classic.lua" scripts. So "booby-classic5.lua" would certainly be a much better file name.
But if you write some script and want me to include it in U61's main distribution, then it will truely make things easier for me if you use the method I used. If you want to look how I have set up my scripts, please look in the "script" folder of the source package.
As of today, if I ever get enough contributed scripts, this is what I'll do:
- Original and well done scripts will be included in the main distribution, that's to say they'll be added to the current scripts, and will use the "library-package" structure.
- Any other other script, as long as it works (no Lua errors, game launchable), will go in a "u61-contrib" package which will contain raw scripts, saved as is.
Of course, as I already mentionned, this is not limitative, if you want to make your own U61 distribution you can do it, as long as it's still GPL'ed. However I'm ready to collect scripts and coordinate the whole project, so you're free to accept my offer or not 8-)
Functions should always be prefixed with the name of the file they are in. This applies to all functions which are defined in the "library" directory. This way, there should never be any conflict between function names. Basically:
- Script callback functions are prefixed with "user_".
- Script API functions are prefixed with "u61_".
- Script library functions are prefixed with "filename_". So a function which is defined in "supercurse.lua" could be name "supercurse_hello_world" for instance. BTW, this implies there should not be any "_" in file names, so that it easier to figure out where the filename ends.
Global constants should always be prefixed with "ID_". As of today, there are 2 types of constants in U61:
- Curse indexes. They are prefixed by "ID_CURSE_".
- Global indexes. They are prefixed by "ID_GLOBAL_".
Since I do not have the time to document all the script library functions in detail, I have decided to provide (at least) a list of the different modules available, and give a short description of what they do. If you want to know more about them, read the code!
Contains the code for the "ANTEDOTE" curse, which gives an antedote to the player.
Contains the code for the "BUGX" curse. The curse replaces the current block by a big X shape.
Contains the code for the "BOOST" curse, which makes the blocks fall very fast for a few seconds.
Contains the code for the "CLEAR" curse. This curse clears the map, ie removes all the squares.
Contains function to match color patterns, such as aligned squares of the same color.
Contains code to generate colored bars, as in the "vertical" set of rules.
Contains a powerfull - but yet the code is ugly 8-} - match function, which search any tetramino, pentamino, hexamino. Well, in fact it just recognizes any sequence of adjacent squares of the same color.
Contains the code for the "DROP" curse, which forces the block to be dropped.
Contains some functions to shift the colors of the block. This can be an alternative to geometrical rotations when the rules are heavily based on colors.
Contains the code for the "FIFTYTWO" curse. When affected by this curse, the user will only get "5" and "2" like tetraminos.
Contains the code for the "GOOFY" curse. This curse inverts the left and right commands.
Contains the code for the "HAHA" curse. This curse writes "HA HA" in the map.
Contains the code for the "HOLEDLINE" curse. This curse adds a line with a missing square at the bottom of the map.
Contains the code to match a line pattern. This means that it detects whenever there's a completed horizontal line of squares, of any color.
Contains the code for the "METAMORPHOSE" curse. It changes the current block to another block.
Contains the code for the "MIXEDLINE" curse. It adds a colored line at the bottom of the map.
Contains the code for the "MORECOLORS" curse. This curse causes some functions to use 7 colors instead of 6, which can sometimes make the game harder.
Contains the code for the "NOHANDS" curse. This curse disables the control of the block, like if keyboard was disabled.
Contains the code for the "ONLYBARS" curse. This curse is a friendly one: it gives the player vertical bars for a given time, which makes the game easier.
Contains some functions to perform geometrical rotations.
Contains the code for the "SHUFFLE" curse. This curse shuffles the map so that evrything gets messy.
Contains the code for the "SIDES" curse. This curse moves the block to the right or left of the map.
Contains the code to "split" a block as it lands. It is used for instance in the "user_land" callback in the "couple" set of rules.
Contains the code for the "STAIRS" curse. This curse draws stairs on the map.
Contains the code to generate tetraminos. Tetraminos are blocked formed of 4 squares.
Contains the code for the "TOPDOWN" curse, which inverts the map, ie puts the blocks that were at the bottom on top.
Contains the code for the "TOPHOLEDLINE" curse, which puts 2 lines with holes in them at the top of the map.
Contains some functions to perform translations of the block without calling 2 API functions (a "get" and a "set").
Contains the code for the "UNSTABLE" curse which makes the map unstable. Contributed by Jimmy Kaplowitz.
Contains various utility fonctions, which are not linked to any peculiar curse or set of rules.
Contains the code for the "WIND" curse. This curse causes the block to move on the left on a regular basis.
This section describes the constants used in the scripts. As you can see, these constants are all defined in capitals, and I used the "ID_" prefix for all of them. I suggest you do the same if you add some, it should keep things simpler 8-)
I won't describe how these constants work in detail, I just give the name of the constants and their value. Please do not assume that, for instance, ID_CURSE_GOOFY is equal to 1, for these values may change some day. The right method when you need a new constant is to pickup a free number, assign it to a variable with a readable name, and then always use this variable.
- 0 : ID_CURSE_ANTEDOTE
- 1 : ID_CURSE_HOLEDLINE
- 2 : ID_CURSE_GOOFY
- 3 : ID_CURSE_CLEAR
- 4 : ID_CURSE_SHUFFLE
- 5 : ID_CURSE_WIND
- 6 : ID_CURSE_FIFTYONE
- 7 : ID_CURSE_BIGX
- 8 : ID_CURSE_MIXEDLINE
- 9 : ID_CURSE_MORECOLORS
- 10 : ID_CURSE_BOOST
- 11 : ID_CURSE_DROP
- 12 : ID_CURSE_TOPDOWN
- 13 : ID_CURSE_TOPHOLEDLINE
- 14 : ID_CURSE_STAIRS
- 15 : ID_CURSE_HAHA
- 16 : ID_CURSE_NOHANDS
- 17 : ID_CURSE_METAMORPHOSE
- 18 : ID_CURSE_SIDES
- 19 : ID_CURSE_ONLYBARS
- 20 : ID_CURSE_UNSTABLE
- 0 : ID_GLOBAL_WIND_COUNTER
- 1 : ID_GLOBAL_WIND_BLOCK_X