matu game engine
- 10 Devlogs
- 26 Total hours
a 2D web game engine, built with js
a 2D web game engine, built with js
Probably my last devlog before working on saving and exporting T-T
I can’t believe I didn’t add this earlier, but you can now end the game using matu.runtime.stop();
You can now have text labels in your game! I also added scripting implementation, so you can change what the text says during a run.
Reordering nodes was a bit clunky, so I fixed it (turns out there were some bugs in the CSS and the dragging), but now it should be smoother!
This is probably gonna be a shorter devlog, but basically I made scripting a lot easier in my game engine!
Each script node now has a button in the top right of the inspector editor. I just reused the asset previews but with a textarea. This means you can have multiple popouts open at a time while scripting. It also gives you a much wider area to code in, as the inspector is kinda cramped. All updates in the popout update with the inspector textarea. The popouts are also resizable!
Before, if you typed tab while scripting, it would just move focus to another button instead of indenting. However, now when you press tab, 4 spaces are added. You can select multiple lines to indent multiple lines, and press shift + tab to unindent lines.
Now when you type a character like ( or [ automatically types its closing pair and places your cursor in between them. If you type the closing pair again, it will move your cursor to the outside. As well as that, deleting an empty pair will delete both characters.
Now when you go to another line, it will inherit the indentation of the line above it. :)
I really thought that with the introduction of scripting popouts, I would be getting close to finishing the project, but over the past few days, I’ve realized that there are still a lot of stuff I want to implement. First, I want to add a Label node, allowing users to display text easily. Next (and I can’t believe I haven’t implemented this yet), I want to add a way for the user to stop the game in the script, instead of clicking the stop button. I want to fix node reordering, as right now it is a bit clunky, and of course, the final thing for me to do is to add exporting, saving, and loading.
It’s been some time since I have posted a devlog on this project. I got a little sidetracked and spent a few days working with Rust. It’s probably gonna be my next project (flashcard app, I know, how original), but I’ve also spent some time working on scripting!
So scripting was actually easier than I thought to implement. I have a const in my runtime.js file called matuAPI and it has every special function as well as what to do when that function is called. I’ll attach a screenshot of a section below. So now, on to what I have added!
Wow, that was a lot! Unfortunately, as I was writing this devlog, I realized that I forgot to add a function that lets you change which sprite is being displayed in an object as well as changing the audio source asset. How does this always happen to me? Ok, I’ll be back in a bit. I need to add that real quick.
Ok, I have returned! I have added them to the code and the documentation (which is just a markdown file), so we also have
Thanks for reading this devlog! Up next, I plan to add a pop out window for scripting (as the current one is too small) and of course, exporting, loading, and saving (I’m scared, save me)
This is probably going to be my last devlog before I work on scripting. I’ve put it off for too long, and right now, scripting is pretty limited (it has a start, end, input detection, movement, and console log function). I plan to add a LOT more to scripting, like changing sprites, changing opacity, rotation, cloning, deleting, audio, preview, and more. I also plan to open up the script in a window similar to the preview windows, because coding in the inspector sidebar is a bit constricting. Now, on to what I have been working on!
I can’t believe I put this off for so long, but it finally works. You can play audio from the preview window. Though, it’s a bit ugly right now so I plan on changing that later.
Before this, the two sliders were just sliders, and you couldn’t bring it to a specific value. However, there are now inputs on the right side of the sliders, allowing you to see what number the slider is at and allowing you to input your own values.
I actually created two systems for this. So my idea for the node naming system is that unique names are kept separate across node types. That means that I can have an object called Thing and a group called Thing. My first idea of implementing this was to create a Set() for each node type. So I created group_names = new Set(), object_names = new Set(), sprite_names = new Set(), and so forth for each node type. Then we reuse the renaming function from script.js for the assets, but change it to have a switch statement based on the type. However, this was kind of hard, implementing a switch statement everywhere a rename or deletion or any sort of change happened. I replaced it by simpling using the hierarchy_nodes Map, which contains the names and types of each node. With this, we can just pull the type from the map to make sure that names are kept separate across types. It removes the big switch statements that were everywhere and overall keeps the code much cleaner.
Previously, you could technically reorder things because I previously added reparenting, allowing you to move nodes from one parent to another, but it doesn’t allow you to rearrange nodes within a parent. Now, you can, and although its a bit clunky, it does work and I think it looks good.
Alright, thanks for coming to this TED talk. The next devlog will be about a lot of changes that I will make to scripting.
I was too lazy to add all the features other than basic functionality to scripting, so I decided to work on some small bugs and features instead.
For the grid in the center of the screen, the function I used to draw it didn’t close it off on the right side. I can’t believe it took until now to fix it :|
I changed the symbols on the left side of each of the nodes from emojis to letters. I used emojis because I didn’t want to find assets (sorry), but recently I’ve been feeling like the emojis make it feel AI-generated, so I removed those. Also, a bonus of changing them to letters is having the ability to now have the same name be used across different node types, but when you call them in code, you have to do like G:Object or O:Object.
You might’ve seen in my last devlog, something kind of crazy happened with the slider… Anyway, it’s fixed now, so that’s good! I also ended up customizing the slider.
Before this, I didn’t have a way for users to lock dimensions. I’ve implemented two checkboxes into the inspector, dimension lock and proportion lock. Dimension lock takes the current dimensions and keeps that ratio, while proportion lock keeps the original dimension ratio of the original asset.
Basically, there used to be a bug where if you deleted one asset while another asset was open in the inspector, it would close the inspector. It wasn’t harmful or anything, but it was really annoying. This was a pretty simple fix. I just added a check where the name of the asset in the inspector is compared to the name of the asset being deleted.
I don’t know if I mentioned this in a previous devlog yet, but I added a console for errors from scripting to show! It also displays start and end times. However, it was the wrong color for so long and I didn’t notice. It was just because I put the wrong class name in the css…
This was also a bug that was really annoying. When you created a sprite and opened it up in the inspector, when you uploaded a new asset, it wouldn’t show up in the inspector. This was also pretty easy to fix. I just created a helper function, which basically just remakes the asset select options, and then called it every time an asset is changed, like when one is renamed, uploaded, or deleted.
I can’t believe I didn’t add this yet, but I added a new option in the inspector. If you have multiple sprites attached to an object, you can now select which sprite to use.
Recently I’ve been working on getting the scripting working. I’m using normal javascript with some added functions with something I call matuAPI. But I’m not here to show that right now. Rather, I think I should show some of the code of how my project works! Today, I want to talk about how I get multiple preview windows!
Every time someone double clicks an asset in the asset panel (which we can check by adding an addEventListener('dblclick', () => {});), a function called openPreview is called. When we call that function, we check to see if a preview of that file is already opened. We have a Map() called preview_windows, which contains all the previews that are currently open. If a preview for that file is already opened, we can simply just bring the preview back to the center of the screen.
Now, what happens if we don’t have a preview open? Then, we create a new div with the class name preview-window. Inside that div, we will have another div for the preview header (which contains the file name and the word “Preview”) and below that div, an img tag with the file image. If the file type is an image, then we set the src of the img to URL.createObjectURL(file). I haven’t had the time to add audio previews yet though…
What happens next? A function called centerWindow is called. It brings the preview div to a select random few points in the middle of the screen. This prevents all the previews from opening up in the same spot. Next, in order to make it draggable, we call a function called dragElement. It detects when the “handle” (the preview header from above) has a mousedown and mouseup event, using a document.addEventListener('mousemove', elementDrag); and document.addEventListener('mouseup', stopDrag);. In each of these functions, we change the position of the element that is being dragged when the mouse is down. We also call a bringToFront function, which just adds a predetermined number to the element’s z-index.
When the user clicks the close button in the header of the preview, we call the closePreview function, which is pretty simple. It removes the name of the file from the preview_windows map, and just deletes the preview.
There were some bugs while making this; renaming issues while a preview is open, the preview not closing when the asset is deleted, and some other elements that had to be added. But I’m pretty proud of the fact that it works and some QoL features that I added to it, like reopening the preview recentering it.
Thanks for reading this all the way down :) Next devlog, I think I’m going to plan on describing how scripting works!
I mean, you can now create them. Peep the screenshot below! I had to create a new .js file because script.js was getting a little crowded. It was getting a little hard to find stuff
I’m pretty proud of how it works, but I’m planning on improving it later.
I’ve added 5 node types.
Groups are used to group other nodes together. Groups can hold other groups or objects directly under them, but no scripts, audios, or sprites.
Objects are like the main nodes you will use. They are you use audio, sprites, and scripts. They can stand alone or go under a group. As you can see, in the inspector, you can edit the x values, y values, width, height, etc.
These 3 nodes require a parent object. They cannot hold anything. This is how you attach images, sounds, and code to your object!
This devlog is a little short compared to my other ones, but I’m still proud of what I have made! This is probably gonna just end up as a prototype for the final node system. I’m planning on adding the option to lock width and height, letting users drag nodes around and locking them, and reordering nodes. Right now, you can just drag them around from group to group, but you can’t change their order.
After finishing the hierarchy, I’m going to move on to getting the coding part of the game engine working. I’m planning on using Javascript or a modified version of Javascript as matu’s language. Maybe I’ll call it matuscript heh
Next, the obvious choice is to work on simulating the game in the viewport. (I’m scared of this)
Finally, I want to work on save files and exporting. I still don’t know how I’m going to accomplish this (I’m even more scared of this)
Maybe I’ll distract myself by working on the looks of matu first.
Anyway, it’s been 2 days since I last posted a devlog. I’ve been focused on making the asset uploading as perfect as possible. You can see everything I’ve done in the screenshot attached below! I’m pretty proud of how it turned out, but it took 6 hours smh… (I’m scared for making the actual game engine part)
Now for the things I did!
This one is pretty obvious. Anyway, I’m pretty proud of how it looks and the fact that it works. In the asset panel at the bottom of the screen, simply click the “+” button at the top right. You will be able to upload any file, though anything that isn’t an image will have an emoji in its place (audio files will have a music emoji and other files will just have the document emoji). It’s totally not because I’m too lazy to actually create a placeholder…
The inspector panel on the right only has one function right now, and that’s to rename assets, but I plan on expanding functionality later on! For example, when we actually get the game engine working, I want users to be able to change the x and y of objects in the game manually, change size, etc. Still, I’m pretty proud of how it looks right now and the fact that it works :)
This one is probably the thing that took the longest. I never want to deal with draggable windows again. Anyway, when you double click on an asset, it opens it up in a preview window. You can drag it around, and that’s pretty much it. But it’s cool
and also it took the longest to make (excluding debugging, which probably took like half of the 6 hours).
Up next, I’m going to work on the actual game engine functionality. First things first, I want the user to create objects in the hierarchy and for things to start showing up in the viewport. I don’t think this should be too hard, but I’m probably gonna regret saying that. Then, I’m gonna get the coding part of the game engine working. I still haven’t decided if I want to create my own language again or just use javascript. I also have to get the game working in the viewport so users can test out their game. Finally, I want to work on being able to export games into html and js.
thanks for coming to my ted talk
I’m building a game engine that I’m calling matu! After around 30 minutes, I’ve finished the basic layout. Right now, it looks a little like Godot, so I’m considering changing it.
You can see what it currently looks like in the screenshot attached. There are 5 sections.
This is where the nodes (sorry for using Godot language, I don’t know what to call them) are going to be held. Stuff like objects, cameras, backgrounds, etc.
This is where the user can upload assets and stuff. I’m probably gonna implement this feature first.
This is where the user can change aspects of each object, like coordinates, size, etc.
So this isn’t actually labelled, but it is the central grid. This is where the user will place objects and where the game will be shown.
This isn’t labelled either, but it’s the panel at the top of the screen. I’m planning on adding run and stop buttons (pretty obvious), save, load, and export features.
Some things that I’m still in the planning phase are where to place scripts and how to add save files. For scripts, I think I’m gonna have one script for each object, but I don’t know where to open them on the screen. For saving, that’s a problem for another day TuT. I have a pretty good idea on how I’m gonna implement Assets and a moderate idea of the Inspector and Hierarchy. Thanks for reading this all the way :)