Minislots Game Engine ===================== Written by Vanessa "VanessaE" Dannenberg This package provides a simple "engine" to drive slimmed-down slot machines. It takes-in money (and pays out, in "currency" mod Minegeld), spins reels, awards wins, and so forth. It features wild cards, variable matching, multiple pay lines, and scatter wins and bonus rounds. Machines are fully themeable, from the biggest parts of the UI graphics to the smallest details of the labels and numerals. Most of the important UI elements' sizes and positions can be controlled. Two example machines are included (described below). Note: As of this writing, the "bonus round" feature is only barely implemented - it only calls a function provided in the machine's definition. This will be expanded-on in time. Depends: Minetest 0.4.17.1 or 5.0.0-dev, a corresponding minetest_game, and Dan Duncombe's currency mod (my fork, which has 50 Mg notes, https://gitlab.com/VanessaE/currency ). Image Geometry: =============== In Minetest, the size and position of an item in a formspec is designated in units equal to the spacing between two squares in your inventory. In this documentation (and elsewhere in this modpack), I use "Inventory Units" or "IU" as shorthand for that. For most things in the Minislots engine, scaling is done such that 64 pixels in the image fits exactly 1 IU, though 1 IU in the formspec doesn't necessarily correspond with any specific number of screen pixels, since that will vary with window and screen size, your Minetest GUI scaling setting, and other things. That's not important here, though, since everything will still maintain proper proportions. Minetest normally uses exact values for sizes, but due to legacy screwiness in how formspecs are rendered, positioning is done at a scale of about 1.2422:1 in the horizontal direction, and 1.1538:1 in the vertical direction, at least for most stuff, and some stuff isn't exact-size either. Furthermore, Minetest doesn't treat the upper-left corner of a formspec as the (0,0) origin, but rather, somewhat below and to the right of that spot (officially it's off by (0.5, 0.5) IU, but in reality, the offset is closer to half of that). A 1x1 IU label/graphic that should be displayed at position (2,2) will end up being 1x1 in size as intended, but positioned at about (2.484,2.308) plus the origin point. The Minislots display engine will position the imagery such that there's a thin shaded border (the default formspec background) around the slot machine's graphics, and it will correct for the above-mentioned legacy scaling and positioning where it can. The cash slot can be almost any size/shape and can be placed anywhere, so that you could, for example, draw it to look like a coin slot, with all the chrome and corrugated edging and such, and position it at the top of the form, to mimic turn-of-the-20th-century-styled machines. That said, bear in mind that when you click on it, you're taken to the "cash intake" screen, where the cash slot image is also shown, at the same size, and in there, it has to fit in between the single intake slot and the inventory slots. The currency label, if printed, is positioned 25% of a digit's width after the end of the amount. It is scaled to the 1.333 times a digit's width to keep it's relative scale correct. It should indicate "Minegeld" in some manner, usually "Mg", as that's what this engine uses internally (from Dan Duncombe's "currency" mod). The "Win" label, if printed, will appear half a digit glyph's width after the Bet amount's currency label. The "Show Pay Lines" and "Show Pay Table" buttons in the help screen are 256x64 px and are always displayed 2x0.5 IU in size, in the lower right corner of the form. Balance, Bet, Win, Scatter Win, and Bonus Win amounts are printed immediately next to their labels. Be sure you leave a little space on the right in the images, as needed. The scatter and bonus highlight boxes are displayed at a size relative to the reel image - 1.3333 times its width, by 0.4444 times its height, and positioned 0.1667 times the reel width above and left, thus centering it over the symbol area. This extra space is to allow one to draw a "box" around the reel symbol, and some kind of "glow" just outside of it, as in the example machines' images. The nominal size of the images is thus 1.3333 times the reel image width by 0.4444 times its height, but because Minetest does not support full image alpha on overlaid images in a formspec (that is, when placing via "image[" rather than compositing with the "^" texture operator), you'll have to fake it by dithering between some color and transparency -- if you need alpha for a glow effect, that is. Draw these images large enough, and the downscaling will blur the dithering, more or less turning it into alpha anyway (it's odd that you can exploit this "fake" alpha, but can't use real alpha). Hence, the images used in these example machines are three times their nominal size. The various labels, parenthesis, and colon in the example machines were drawn with The GIMP using the "Liberation Sans Narrow Bold Condensed" font, 85 point height, with the inter-character spacing set as small as the wording would allow (usually -4.0). Anti-aliasing enabled, "Full" hinting. Text is positioned two pixels from the left, with the baseline at 60 (so the lower left corner of the "B" in "Bal:" is at (2,60) according to GIMP). The numerals use "Century Schoolbook L Bold" font, same size, settings, etc. Same vertical positioning, and horizontally-centered. Reels always show three symbols' of height, not counting the overlap at the top and bottom to allow for symbols to be positioned "off-screen". The pay table, pay lines, admin, and cashout voucher screens all use the Liberation Sans font (either condensed, regular, or bold). Geometry for the 3-reel "Golden 7's" machine: --------------------------------------------- The upper overlay, reel underlay, and line win overlays are 832x704 px --> 13 x 11 IU The lower overlay image is 832x128 px --> 13 x 2 IU A single reel image is 192x576 px --> 3 x 9 IU A digit glyph is 48x80 px, or 0.75 IU, but is displayed at 75%, 45% or 40 %% of that size, depending on line height (to fit in large values) --> 0.563, 0.338, or 0.30 IU The currency label is 96x80 px --> 0.4 x screen_line_height_3 IU The "Bal", "Bet" and "Win" labels are 128x80 px, but should be narrower --> 1.125 x line_height IU The "Line Win" label is 256x80 px, should be displayed at 50% width --> 3.0 x screen_line_height_3 IU A colon or parenthesis is 24x80 pixels, displayed at 50% digit width --> 0.188 x screen_line_height_3 IU The "Scatter Win" is 384x80 px, should be displayed at 50% width --> 3.0 x screen_line_height_3 IU The "Bonus Win" label is 352x80 px, should be displayed at 50% width --> 2.75 x screen_line_height 3 IU The cash slot is 320x128 px and is normally shown at full-size --> 5.0 x 2.0 IU The "screen" in the lower overlay is 384x112 px --> 6.0 x 0.875 IU. The Scatter and Bonus highlight boxes are 768x768px --> 4.0 x 4.0 IU Geometry for the 5-reel "Golden 7's Deluxe" machine: ---------------------------------------------------- The upper overlay, reel underlay, and line win overlays are 939x704 px --> 14.667 x 11 IU The lower overlay image is 939x128 px --> 14.667 x 2 IU A single reel image is 128x576 px --> 2 x 9 IU A digit glyph is 48x80 px --> 0.563, 0.338, or 0.30 IU The currency label is 96x80 px --> 0.4 x screen_line_height_3 IU The "Bal", "Bet" and "Win" labels are 128x80 px --> 1.125 x line_height IU The "Line Win" label is 256x80 px --> 3.0 x screen_line_height_3 IU A colon or parenthesis is 24x80 pixels --> 0.188 x screen_line_height_3 IU The "Scatter Win" label is 384x80 px --> 3.0 x screen_line_height_3 IU The "Bonus Win" label is 352x80 px --> 2.75 x screen_line_height 3 IU The cash slot is 320x128 px --> 5.0 x 2.0 IU The "screen" in the lower overlay is 426x112 px --> 6.656 x 0.875 IU. The Scatter and Bonus highlight boxes are 512x768 px --> 2.667 x 4.0 IU Matching: ========= In most cases, line matches are pretty straightforward. If you specify a line in your match table reading: {123, "cherry", "lemon", "melon", "bell", "bar"} ...then any pay line with those five symbols in exactly that order will be considered a win, and the player will be awarded 123 times their line bet. If an entry in the list is nil, for example: { 99, "cherry", "lemon", "melon", "bell", nil} ...then the corresponding reel will be ignored when checking if that entry is a match (reel 5 in this case). This can be used for various effects, but mainly, it's intended to let you specify a match that only needs a few matching symbols on the first few reels, rather than requiring all five (or whatever) reels to match on a pay line, such as a match of three of some symbol on a five reel machine (one assumes that such a machine would have matches programmed for four or five of that symbol as well, at progressively higher values). If an entry in the list is itself a list, then the the items in that sub-list mean "any of these can match". So if you have a match entry like: {100, "777", "777", "777", "777", {"7", "77", "777"} } ...then reels 1, 2, 3, and 4 would need to show a [777] symbol, and reel 5 would need to have one of [7], [77], or [777] also to complete the match (which would pay 100 times the line bet). You can do this for any reels you want, with as many entries in each sub-list as you want (well, up to however many the machine has, of course). For example, the Golden 7's Deluxe machine has an entry in its pay table that pays out on a line win consisting of five assorted [7], [77], and/or [777] symbols (it also has one for assorted [bar], [2bar], and/or [3bar] symbols). The human-readable pay table and pay lines screen: ================================================== The format of the paytable_desc is pretty simple - it's a table of tables. :-) Each line in the table represents one line in the pay table screen. Each item in the line is either a chunk of text or a symbol prefixed with an "@". In order to allow mixing symbols among text, it is necessary to break the line up, because the parser can't decode flat, mixed lines. So if you have a line reading: { "Any three mixed ", "@bar", "/", "@2bar", "/", "@3bar", " pays 10" }, This will tell the parser-renderer to place the phrase "Any three mixed ", then right next to it the "bar" symbol. A slash next to that, then a 2-bar, another slash, a 3-bar, then the phrase "pays 10". All of that placed on one line. You can have as many lines as your layout and text size permit, and you may mix-and-match symbol and text items freely. The special symbol "@X" tells the parser to insert a blank space equal to the size of a symbol - this is useful for making grids of symbols with some spaces left empty (as in a 3-out-of-5 reel match). The parser doesn't have any text positioning commands yet, other than "@wrap" (below), but some rudimentary layout formatting can be accomplished by inserting blank lines or chunks of whitespace between items. For a layout with fairly large text/symbols as in the 3-reel demo machine, there's room for up to 19 lines, as long as the top line is not so long that it overlaps the [X] button. For a layout like the 5-reel machine, with its smaller text, You can fit up to about 25 lines. Of course, you can just set your line height to fit more text. The symbols are of course picked from the "stopped" reel strip image, and they are always cropped square, so on a machine like the 5-reel demo, only the middle 128x128 pixel section of each 128x192 pixel symbol would be shown. For the pay lines screen, the item format is simplified. One table item per screen line, which can be either a line of text, or a key indicating that one or more pay line images should overlaid onto their background image and placed on the line. The key for those is "@" followed by a number, a space, and another number (e.g. "@1 5"). These numbers indicate the first and last pay line images to display. On both screens, lines are "printed" from top to bottom in a column toward the left side of the form background, overflowing into a second column if necessary. You can force an overflow into column 2 by inserting a table entry consisting of the string "@wrap" (in the case of the pay table, it must be on a line by itself, and not inside an inner table the way the other items are). If paytable_desc or paylines_desc is not specified, then only the background, [X] button, and "Show Pay Lines" or "Show Pay Table" button will be displayed on their respective screens. This allows you to use the background image itself as the pay table/lines description, in the event that you want to skip the text/image printing routines and just roll your own. How wild cards work: ==================== [WILD!] is basically "don't care", as far as the engine's concerned, and will match the highest entry in the table that can theoretically form a match, regardless of how many symbols actually match, except if a wild_doesnt_match table is also specified in the machine definition. This table should be self-explanatory -- whatever symbols are listed there, a [WILD!] symbol will not match, regardless of its position in the payline or the value of a given match line. For example, suppose you get a normal-looking spin showing [WILD!][77][77][lemon][cherry] on a line on the 5-reel demo machine. That won't match anything, because there's no match line that allows for a match consisting of only three "7" symbols of any kind. On the other hand, suppose you get [WILD!][WILD!][WILD!][2bar][cherry]. Sounds like it should match the {"2bar", "2bar", "2bar", "2bar", nil} entry, but it'll pick the {"3bar", "3bar", "3bar", nil, nil} entry, because that one also matches, but it's worth more. This extends to as many reels as the machine has, and as many [WILD!]'s as there are in a pay line, regardless of where in the line they appear (so long as the symbols that precede and follow the [WILD!]'s can form valid matches, of course). A pay line consisting of all [WILD!]'s is equivalent to whatever the highest winning combination is in your machine, that doesn't also contain any symbols in the wild_doesnt_match table (three or five [777]'s in the Golden 7's example machines, because they're both set to not match against [JACKPOT!]). If a wild multiplier is in effect, it'll be applied to the final value for a given match. Each wild card multiplies the win by the configured amount, but only for wild cards that actually helped create a win. Thus, the final win amount will be line_win * ( wild_multiplier ^ number_of_wilds ). DISCLAIMER: =========== THIS IS A SLOT MACHINE "MINI GAME" PROJECT FOR THE MINETEST OPEN SOURCE GAME ENGINE/PLATFORM. IT IS NOT IN ANY WAY, SHAPE, OR FORM ASSOCIATED WITH, REGULATED BY, OR OTHERWISE UNDER THE CONTROL OR INFLUENCE OF ANY LOCAL, COUNTY, STATE, OR FEDERAL GAMING AGENCY, COMMISSION, OR OFFICE. THE "CURRENCY" USED BY THIS PROJECT IS ENTIRELY FICTIONAL, EXISTING ONLY WITHIN THE ONLINE WORLD FOR WHICH IT WAS CREATED, AND NO PART OF THIS PROJECT SEEKS TO MAKE IT CONVERTIBLE, EXCHANGEABLE, OR OTHERWISE NEGOTIABLE FROM OR INTO ANY LEGAL TENDER CURRENCY OR OTHER VALUABLE ASSETS OF ANY KIND OR ORIGIN, WHETHER TANGIBLE OR INTANGIBLE, PHYSICAL OR ELECTRONIC. NO CLAIMS REGARDING THE FITNESS OF THIS PROJECT FOR ANY PURPOSE ARE HEREIN MADE, AND NO WARRANTY OR GUARANTEE OF ANY KIND IS OFFERED BY ANY PARTY. SEE ALSO, "LICENSE" IN THE MAIN PROJECT DIRECTORY.