This post is for people who want a custom, dynamic overlay and know how to program.
As for why you'd want an overlay in the first place, here are common uses:
!game
or !help
Regarding the dynamic aspect—your streaming software can already render text and graphics. However, it may not allow for event-based triggers or animations. For example, I made a custom overlay that reads a file from my system, fades in a marquee with that text every so often, then fades it out when enough time has elapsed. With my streaming software, I only would have been able to render static text on the stream.
I use OBS, so I'll talk about its specifics here, but software like XSplit also supports this method.
OBS has a built-in "Browser" source that lets you show the contents of a webpage:
From there, you type in a file path or URL, and OBS will render whatever you would see if you had pointed your actual browser at the same page:
That means that you "only" have to make a webpage with your overlay's contents. If you wanted something basic enough, you could write a simple HTML file with CSS animations. However, this is where game engines really shine since they're built to handle graphics, animations, and even sounds! As long as the game engine can export to HTML, then you can use it to make overlays.
I prefer to use Phaser since it's relatively easy to learn. It's also specifically intended for WebGL games, which means you can just save your JavaScript file as you're working and click "refresh cache of current page" in OBS to see your changes (as opposed to having to export a build from your game engine).
If you want a more visual game engine that can still export to HTML, consider Godot, which I made a great course on!
If you put everything into a standalone HTML file and load Phaser from a CDN, you won't need a web server running anywhere. On the flip side, it also means that you can't read any files from your hard drive, including JavaScript files, so you'll need to place all of your JavaScript inside the HTML file itself.
This HTML snippet will float the word "Hello" from the bottom of the screen to the top:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/phaser@3.23.0/dist/phaser.js"></script>
<style>body { margin: 0; }</style>
<script>
let textObject = null;
const width = 1920;
const height = 1080;
const phaserGame = new Phaser.Game({
type: Phaser.WEBGL,
scale: {
mode: Phaser.Scale.FIT,
width,
height,
},
transparent: true,
scene: {
update,
create,
},
});
function update(time, delta) {
textObject.y -= delta / 20;
}
function create() {
textObject = this.add.text(0, 0, "Hello world", {
font: "64px Lato",
fill: "#0000ff"
});
textObject.x = width / 2 - textObject.displayWidth / 2;
textObject.y = height + textObject.displayHeight;
}
</script>
</head>
<body></body>
</html>
You can use this as a foundational overlay via any of these three methods that I'm outlining here by saving the contents as index.html
and pointing OBS at it.
Using any web server (e.g. http-server for Node.js, Python's http.server, or even something heavier like Apache's HTTP server), you can serve a directory from your hard drive and point OBS at the resulting local URL. For example, I run Node.js's server via
http-server -p 5896 .
Then, I can point OBS at http://127.0.0.1:5896
Running a web server allows you to load files from the directory that you're serving. This means that you can separate out the JavaScript from the HTML:
1
2
3
4
5
6
7
<html>
<head>
<script src="phaser_3_23_0.js"></script>
<script src="main.js"></script>
</head>
<body></body>
</html>
This has an added benefit of fetching Phaser directly from your hard drive rather than a CDN, so it will load faster.
While this works and gives you flexibility, you'll need the web server running any time you want to stream. I solve that particular problem by creating a prestream.cmd
file that I run before each stream. It sets my microphone volume, starts my chat bot, and serves my stream overlays.
OBS supports using an online URL instead of a local path. This is how services like Streamlabs work; they host a page for you to use from OBS.
I only suggest putting a server online if:
A natural next step would be to integrate features from your streaming platform directly into your overlays. For example, when someone follows the channel, you may want to spawn fireworks in your overlay. In order to accomplish this, you would need to connect to the streaming platform's API.
I want to keep this blog post brief, so I'll just outline one possible solution for this in the form of a stream-event microservice:
Making your own overlay is a great way to achieve a specific effect and stand out from template-users. If you already know a game engine or rendering library that can output to HTML, then there's practically no setup involved. Otherwise, there'll be a bit of a learning curve, so unless you require custom functionality, then it may not be worth pursuing.
If you enjoyed this post, consider taking a look through the courses that I offer:
Check out my courses