This is being built for the most recent builds of GM, which are now just known as GameMaker Studio 2023+
LemonToast Games
Creator of
Recent community posts
Introduction
Welcome to the LUI system guide! This comprehensive guide will walk you through harnessing the power of LUI to create immersive and intuitive user interfaces for your games. Whether you're a seasoned developer or new to GameMaker, this tutorial will equip you with the knowledge to craft functional UI elements.
Step 1: Setting Up the LUI System
To begin, let's create a LUI system in the create event of your object. This essential step establishes the groundwork for constructing your UI components seamlessly throughout your game/app. You can have as many LUI systems as you want in your game.
// Create LUI system LUISys = LUI_Create_System();
After creating the LUI system, you need to implement step and draw events to ensure everything just works.
// Step Event: Call LUI_Step for each LUI system // and 'x' and 'y' with the desired coordinates, these are optional arguments LUI_Step(LUISys, x, y);
// Draw Event: Call LUI_Draw for each LUI system // and 'x' and 'y' with the desired coordinates, these are optional arguments, // but can be used to draw the UI at a different position in a non destructive way LUI_Draw(LUISys, x, y);
Step 2: Define UI Elements
With the LUI system in place, let's explore each available LUI element and how to effectively incorporate them into your game's UI:
Empty
Empty elements act as placeholders within the UI hierarchy and are useful for organizing and structuring your UI layout.
var empty = new LUI_Empty(system, x, y, parent_element);
system
: The container or parent element for the empty element.x
,y
: The coordinates to position the empty element.parent_element
(optional): The parent element within which this image resides.
LUI_Empties also include the following variables:
- xshift/yshift: can be used to nudge the element in any direction without affecting their placement in the UI system, good for adding a "shake" effect to parts of the UI non destructively
- width/height Typically zero, can be read after creating for organizational means
- xpin/ypin: Set from 0-1 can make a empty's placement in the UI dynamically pinned to a certain portion of the total UI system area. Useful for pinning elements to any of the corners of the UI area, or centering elements, etc. If the UI area changes at all, the placement of the Empty will automatically adjust.
- visible: self explanatory.
Images
Images are an indispensable part of the LUI system framework.
var image = new LUI_Image(system, sprite, subimage, x, y, parent_element);
parent
: The container or parent element for the image.sprite
: The index of the sprite to display.subimage
: The specific frame within the sprite.x
,y
: The coordinates to position the image.parent_element
(optional): The parent element within which this image resides.
LUI_Images also contain the following variables:
- visible: Determines if the image is visible. Default is true.
- xshift, yshift: Shifts the image horizontally and vertically non destructively.
- xpin, ypin: Sets the horizontal and vertical pinning of the image in the UI area.
- xspan, yspan: Spans the image's width and height within the UI area.
- spanPad: Padding around the image when spanning.
- xscale, yscale: Scales the image horizontally and vertically.
- angle: Rotates the image (in degrees).
- color: Sets the color tint of the image.
- alpha: Sets the transparency of the image.
- left, top: Sets the left and top cropping of the image.
- hpercent, vpercent: Sets the horizontal and vertical cropping percentages of the image.
- isButton: Indicates if the image behaves as a button.
- callback: Function to call when the image is interacted with.
- active: Determines if the image is active and can be interacted with. Default is true.
- deactivated: Indicates if the image has been deactivated. Default is false.
Text
Text elements provide crucial textual information to players, such as instructions, dialogue, or game statistics.
var text = new LUI_Text(system, text_string, x, y, font, typewriter, alignment, parent_element);
parent
: The container or parent element for the text.text_string
: The text to display.x
,y
: The coordinates to position the text.font
: The font style for the text.typewriter
(optional): Whether the text is written to the UI one letter at a time, emulating a type writer effectalignment
(optional): The alignment of the text (left, center, or right).parent_element
(optional): The parent element within which this text resides.
LUI_Text also contains the following variable:s
TabPanel
Tab panels organize content into tabs, allowing players to navigate between different sections of your UI with ease.
var tabs = new LUI_TabPanel(system, background_sprite, tab_sprite, padding, x, y, parent_element); tabs.define(width, height, tab_labels, tab_width, tab_height, tab_spacing, font);
parent
: The container or parent element for the tab panel.background_sprite
: The sprite index of the panel background.tab_sprite
: The sprite index of the tab.padding
: The padding around the tabs.x
,y
: The coordinates to position the tab panel.parent_element
(optional): The parent element within which this text resides.
TabPanel also contains the following variables:
Panel
Panels serve as containers for other UI elements, allowing you to group elements together and organize your UI layout effectively.
var panel = new LUI_Panel(system, background_sprite, padding, x, y, resizable, parent_element); panel.define(width, height);
parent
: The container or parent element for the panel.background_sprite
: The sprite index of the panel background.padding
: The padding around the panel.x
,y
: The coordinates to position the panel.- resizable: whether the panel can be resized or not
parent_element
(optional): The parent element within which this text resides.
LUI_Panel also contains the following variables:
Checkbox
Checkboxes enable players to select or deselect an option, providing interactive functionality within your UI.
var checkbox = new LUI_Checkbox(system, checkbox_sprite, states, x, y, parent_element);
parent
: The container or parent element for the checkbox.checkbox_sprite
: The sprite index of the checkbox.states
: An array specifying the subimage indices for the checked and unchecked states.x
,y
: The coordinates to position the checkbox.parent_element
(optional): The parent element within which this text resides.
RadioButton
Radio buttons allow players to select a single option from a group of options, facilitating decision-making within your game.
var radio_group = new LUI_RadioGroup(); var radioButton1 = new LUI_RadioButton(system, radioButton_sprite, states, x, y, parent_element, radio_group); var radioButton2 = new LUI_RadioButton(system, radioButton_sprite, states, x, y, parent_element, radio_group); var radioButton3 etc...
parent
: The container or parent element for the radio button.radioButton_sprite
: The sprite index of the radio button.states
: An array specifying the subimage indices for the checked and unchecked states.x
,y
: The coordinates to position the radio button.parent_element
(optional): The parent element within which this text resides.
radio_group
: An instance ofLUI_RadioGroup
to manage the radio button group.
Practical Examples
It's important to pay attention to the hierarchical structure of the LUI system. Any element can be a parent of any other element, and as such, their positions will be relative to each other.
Let's take a look at the following example from the included demo:
var empty = new LUI_Empty(panel,0,0); empty.xpin = 0.5; yy += tabH/2; var headerback = new LUI_Image(panel,spr_BarTest,0,0,yy-tabH/2,empty); headerback.isButton = true; headerback.xspan = 0.5; headerback.spanPad = 0; headerback.height = tabH; var dat = new LUI_Text(panel,"RADIO BUTTONS",xx,yy,Font1,false,fa_left,empty); dat.valign = fa_middle; yy += tabH-padding;
Above you can see an empty being created inside of a system called "panel." This empty is given an xpin value of 0.5, this means that it will be placed in the middle of the UI area along the x axis, so as the UI area changes, this empty will adjust automatically to always be pinned to the center.
headerback and dat are both parented to empty. This means wherever empty goes, they will follow. The xposition of headerback will be equal to that of empty, but the y value of headerback will be equal to empty plus whatever the value of yy is minus half of the value of tabH.
dat will be placed at the position of empty.x/y PLUS the values of xx/yy. Therefore if xx and yy are both equal to zero then the position of dat would be equal to that of empty.
Still with me? Great! Let's take a short break for now, I'll be back with more updates soon, so keep your eyes peeled!
Make sure that separate texture page is set to on for any dither or lut texture you might use.
Here's a breakdown of the RFX_Init function:
RFX_init(pixel width, dither texture, dither spread, SSAA(?), double wide pixels(?))
- Pixel Width: How wide the pixels are on screen, 1 is unchanged from screen resolution, 2 two pixels wide, etc. Basically the bigger this number, the chunkier the graphics.
- Dither texture should be pretty self explanatory, just use sprite_get_texture(dither_sprite,image_index)
- Dither Spread, this controls how much dithering is visible, I used numbers between 32 and 256. The higher the number, the less dithering there is visible in the final result.
- SSAA is an optional argument that enables or disables full screen antialiasing. It can result in a smoother looking image with a higher number. Be careful not to go too high or you will end up with a blurry looking final result.
- Double Wide Pixels: This is the effect used in the thumbnail of this asset. It just makes each pixel twice as wide. It's a neat effect in my opinion, but some folks might not prefer it, therefore it is an optional argument.
I've never posted about this here, it's not really new, but it's got a permanent new sale price just in time for your holiday metallic animations.
[Blender] Medle - Antique And Oxidize Metal Shader
This is a stylized shader node for cycles, with presets that model nearly any kind of metal, antiquing, and oxidation. The node comes with presets for materials like copper, iron, aluminum, and more. It ships with a standard material with loads of configurable settings, and a simplified material for those looking to get started quickly. Included are also sample CC0 textures for oxidation, water leaks, metal wear, and imperfections.
https://cdlegasse.itch.io/blender-medle-shader
If you have any questions feel free to post em here!
https://cdlegasse.itch.io/retro-dither-shader-gamemaker-studio
I have been working on this set of shaders off and on for a while and decided to share the most recent version of them with you. You can find more information on them at the link above.
Here are some screenies to whet your whistles!
Hey all, I just released my TGA loader asset for Gamemaker to help fund the development of Ozarq, my BSP loader.
It's only a dollar and supports a wide range of TGA formats, including RLE and PackBits compression.
When Ozarq is complete, it will release for free and will come with the TGA loader, so if you want a copy but don't want to pay a buck, you can wait however long it takes me to complete Ozarq lol.
I'm very glad you do! You'll be excited to know that I'm currently working on texture packing, so each unique texture will no longer be a separate draw call! It's already working on floor and ceiling textures! :P Once the walls and floor are implemented, there should be some dramatic frame rate boosts!
Combat Cats is a tile-matching game with unique combat aspects that add RPG and adventure elements. Kitty Island is in shambles. This once purrfect paradise is now without an ounce of catnip. You, a member of the Kitty Island Homeland Security's veteran Ace Fighter Pilots, are the last hope to return peace and harmony.
Find out more here:
With the Wad Lab beta release looming ever closer, I felt it was a great time to share some vital information to prepare you for playing around with some DopeFish goodness.
First thing's first, what is the Wad Lab, and how does it differ from DopeFish?
Wad Lab is sort of a testbed, it is powered by the DopeFish engine, but it is NOT the DopeFish engine. Instead this tool gives you the ability to test out new features of the engine on your own wads, given that you follow the proper protocol. And don't worry, this will get easier as the engine gains more features!
How can you use the Wad Lab with your own wads? Well there are a few important rules to follow. Currently DopeFish only works correctly wads that have been processed by supported Node Builders. Currently the only supported node builder is GLBSP. Luckily Wad Lab comes with GLBSP included, and instructions on how to use it! In the future more node builders will be supported, and DopeFish may even come with one built in, leaving less for you to worry about!
Let's look at the UI!
You'll notice a readout on the right side of the screen, this will tells you various bits of information gleamed from the wad that you have loaded. It will also display any warnings, such as if there's no wad currently loaded, or if the wad is of an unsupported format.
On the left side of the screen you'll see our game window. This is here for a very important reason. Wad files contain sprites that are specific to a certain game. Each of the available games here contain their own database, however entries from a database in the game Heretic may be referenced using the same ID as some entry from the game Doom. So knowing which database to check is very important, and unfortunately, wads do not have any information stored in them that can tell the system what game they are for. Therefore the user must decide that.
Under the game window are your configuration settings. Load wad is self explanatory, but skill and multiplayer may be a bit confusing if you're not used to working with the wad format. See, items and creatures on a map can be assigned certain tags, such as skill number, or multiplayer. What these do is tell the game that will be loading the map that these entities should only be spawned if the game settings match the assigned tags. So if you set the Skill to 3, then only entities that are meant for a level difficulty of three or lower will be added to the map. Add thusly, toggling the multiplayer switch to the on position will tell the Wad Lab to load any entities on the map that are tagged for multiplayer.
And finally we have the map setting, and launch. It's pretty apparent what map does, simply typing in the name of a map in the wad will tell the game which level to transport you to when you click launch. However if you're not aware, in traditional wads, there are two ways a map can be named, ExNy, where x represents an episode or chapter, and y represents what map number in that episode or chapter. Such as E2M4 will take you to Episode 2, Map 4. And then there is the MAPxx format, where xx represents a any two digit number, traditionally from 01-32 or higher in some cases.
How will you know which naming convention to use? Well when you're designing your own levels you can choose whichever feels the best for you. However when loading from any of the wads that the Wad Lab ships with, the following rules will apply:
Freedoom, Doom, and Heretic all use the ExMy format.
Freedoom 2, Doom 2, and Hexen all use the MAPxx format.
Once you've entered in all of your configuration settings you're ready to play. Just hit the launch button and let the system load. If your wad isn't broken and you've chosen a valid map name you will be transported into a fantastical new world of pixelated and low poly goodness. The controls in this world are very simple, "WASD" to move around, "Space" to jump, and press "F" to pay re.... to interact with doors and switches. Pressing the "Enter" key will unlock the mouse from the screen and pressing the "Esc" key will terminate the program freeing you to go about your business.
That's really about all there is to know about the Wad Lab! The first release is coming very soon, but keep in mind this is all a work in progress, and that you will be playing with the Wad Lab at your own risk. The frame rates will be abysmal in some levels until further features are implemented into the DopeFish render pipeline. Things may even crash or make really abrupt and startling noises! That's okay, It's all being worked on! ( by one guy, give me a break man! :P )