2D Lighting for GameMaker Studio 2 January 15th 2019
I decided to write a lighting system for GameMaker Studio 2 because I wasn't super satisfied with the availability of lighting in the GameMaker ecosystem. One of my priorities were to demystify a system like this and ensure that everyone can pick it up, learn from it and understand what's going on, and integrate and adapt it to their game projects. That's not to say that this is by any means a "gold standard". It's not, but this is what I wrote and it's free and looks alright. I am releasing this system for free under the MIT License, and it is open-source so everyone can make it better and modify it to their heart's content. I welcome additions and bug fixes to the general design of the lighting system back into the repository so all users benefit from your cleverness - full credit is of course given.
This is a lightweight shader lighting system for dynamic pixel lights that composites multiple lights into a single surface. The surface is fitted to a "camera" that is used to perform the lighting pass.
Instances that inherit from the object
obj_shadow_caster are able to cast shadows, and lights are placed and configured in the game with instances of
obj_light. It has good support for object variables.
It is my desire to provide a general lighting system that could be further customized to suit the needs of each specific game project it is used in. To get the best performance, or lighting quality, or whatever else, for your game you will probably end up modifying it to some extent. It might also work well for your game or prototype out-of-the-box by tweaking some of the knobs.
You can easily upgrade the lighting system, once integrated in your game, to a newer version by simply replacing the previous version's assets in your project. It also tracks various statistics (if you opt in) that help you optimize your use of the system.
The video above shows a test game where the lighting system was put in later in development by simply dragging objects into the room.
Learn how to use this lighting system with Shaun Spalding's introduction video: https://www.youtube.com/watch?v=RFRV3lhVOhg.
The repository is hosted on GitHub and is available here: https://github.com/borup3/Lighting-System-2D.
The demo project repository is also hosted on GitHub and is available here: https://github.com/borup3/Lighting-System-2D-Demos.
It is also available on the Marketplace: https://marketplace.yoyogames.com/assets/7820/lighting-system-2d.
I have prepared a small demo of the lighting system to show what it's capable of in the hands of a moderately bad environment designer in a short time span. This demo is a virtual tour of the different types of light in a single level. This demo is not by any means a gold (or even good) standard: for a game project you should do a lot of things different from this demo. Demos are always time sinks so I decided to leave it in its current sort of unimpressive state. You are of course free to improve this, or make better demos, too.
You can download the demo of the lighting system here: Lighting_Demo_01.zip (binary only).
Note that while this demo is not included with the lighting system project, a selection of testbed rooms are.
Lights are defined as a set of attributes that determine their behavior, so they are decoupled from the object that created them. These attributes include spatial information, rendering attributes like color, range and intensity and what type of light to use.
The following light types are supported at the time of writing:
PointOmnidirectional point emitter
SpotConical point emitter
AreaUnidirectional line emitter
LineBidirectional line emitter
DirectionalInfinite directional light without an emitter source
These light types give you a lot of possibilities for lighting up your game worlds.
A shadow caster is nothing more than a user-defined polygon and a bitmask enum to mark a shadow caster as static, dirty and so on. Shadow casters are by default non-static (for easier use by novices). Scripts are included to create a polygon from the axis-aligned or rotated bounding box of an instance and from a path resource for more complex polygons. This allows you to define complex polygons by tracing sprites on a room path layer and apply rotations with the path_orientation variable.
By toggling the global variable
shadowCastersCullByCollisionMask you can control whether to cull shadow casters by their collision masks using an R-tree algorithm or linearly by their polygons. There may be a performance improvement to be had when using the R-tree algorithm, so the default value of this variable is
I believe the code is sufficiently documented and with the addition of several test rooms and the demo project, I don't feel further documentation is required. For example, the lighting system contains only 4 objects: the initialization object, the renderer object, the light object and the shadow caster object.
A testbed room included with the lighting system project.