What has been accomplished
Conversion is done! The Unity project I had has been essentially recreated in Defold, with some extra small features.
- The player can move left and right, jump, and double jump
- The player can mine blocks (they just disappear for now)
- The player can place blocks, decrementing the store of items in their toolbar
- The world is tracked by chunks and blocks by position
I struggled for a bit wondering how best to track the world chunks because I was unsatisfied with how I had done it in Unity.
I tried a bunch of different techniques, but I settled on something I believe to be greatly scalable and (with a little math thrown into some helper functions) very simple to use!
The short version of it is this:
- The world consists of a 2D Lua table of chunks
- Each chunk consists of a 2D table of blocks.
- Each chunk contains a position representing its index in the world’s 2D chunk table and consequently in the game world itself
- Each block contains a position with these bounds 0 <= x < 12 and 0 <= y < 12 representing its index in the chunk’s 2D block table
The world and chunk object are currently largely analagous structures, but I anticipate great differences later on so I have separated them for now. By choosing this model, using Rendercam’s screen_to_world_2d function and some interesting math, I am able to directly index what chunk and block a user click is interacting with.
Problems I ran into
I did not really want to deal with Defold’s built-in camera on my own and I knew I would need later to map screen positions to world positions, so I sought out my options. I first tried out Orthographic Camera but I failed to get this to work. After a few hours, I switch to Rendercam and it worked immediately for me (If anyone wants to pull my code and try to map everything over to Orthographic Camera, feel free to do so since it has more features, otherwise, I will be sticking with what I got).
If anyone was particularly perceptive, you may have also caught a post I made about issues with collisions. Thankfully, britzl was wonderfully helpful and suggested Platypus, a minimalist 2D platforming engine for Defold. With only a little setup (which was well-documented), my problems were solved and I was able to move right along.
I will be focusing most of my time coming up on allowing the player to pick up broken blocks, and implement the beginnings of a true inventory system. The game in general is going to stay pretty visually unappealing as I get these base functionalities in. Thankfully, Defold seems to do a good job of separating the logic of animations and the beauty of the game you are developing that you can develop with that in the back of your mind. Once I believe Chemaria is in a confident state, I will begin to improve the visuals.
Farewell for now!
I want to thank the Defold community, for you all have already been very supportive and responsive in a unique way. And that is that, talk to you all later!
britzl was able to provide some help in fixing the use of the orthographic camera and we fixed a breaking bug in the game only present when built. Here is a little update picture from the first dirt hut of many to come!
The beginnings of the inventory system are here!
Right now it has the same functionality as the toolbar, where it simply highlights selected items. Unlike the toolbar, it does not determine what blocks are being placed.
The next step is to implement some kind of drag and drop on the inventory to allow arranging and moving items to the toolbar.
World Generation/Loading/Saving Revamp!
Calling all of this a revamp is a little misleading, whoops. I did change the world generation a bit, becoming more general for right now in early development.
I also removed all of my up-pointers from Chunk and Block (before they had a pointer from the Chunk to its World and from a Block to its Chunk). This was changed to make printing an object easier (no more truncated output on printing one block) and to allow saving the World to a file (same issue with infinite recursion on the Lua table due to the pointers). The pointers were instead replaced with a position vector I can use to obtain the relevant object from my collections pretty simply in code.
Saving and loading does now work though…in a limited fashion. I am using
sys.load() provided by Defold, but I am already running into size issues when saving the world to a single file, and the saveable world is FAR from the intended size of the game world of the final product. I looked into other implementations for saving a table to a file, but none of them worked with
userdata (understandable because it can change drastically between programs. This becomes a problem due to the
vector3 provided by the
vmath library.) I believe I could make a workaround by simply storing a table with x, y, and z values and then map them to vectors on load from the file, and then implement one of the many options out there for saving large tables to files. If anyone has a better suggestion though, I am totally open to any help one could give.
I believe this use case for
sys.load() were simply not meant for tables of this size for games of this scale, which is understandable given Defold’s beginnings as a game engine for mobile games, but as the engine expands its kingdom into these other gaming platforms, the ability to save files larger than 512kb may become necessary sooner than later. I posted an issue to Github regarding this.
P.S. Sorry about the posts being shifted around and reposted. I got the no more than 3 consecutive posts message and did not understand what it meant at first (It’s late at night, give me a break) but now I understand better. Will not happen again!
Have you ever needed to organize the piles of dirt in your pocket? Well in Chemaria, now you can do just that!
You can notice a few changes already in this screenshot. First, we finally have textures on the item slots of the toolbar and the inventory. On top of that, item stacks can be dragged and dropped between the toolbar and inventory with ease.
I expected this to be much harder to solve than it actually ended up being. The problems I ran into caused me to generalize the way I index the collections in the UI (toolbar and inventory) and now there is a general solution written to swap items back and forth in the UI.
What is next?
As of right now, if you desire to make a lot of pixel art, once you run out of those 10 stacks of 64 dirt you are out of luck. So I believe the next most important feature Chemaria needs is the ability to pick up broken blocks/items. I anticipate this being a fairly simple feature, but as any developer knows, this could turn into an absurdly large endeavor for the smallest unexpected reason.
Future of Chemaria
Defold has sped up the process of making this game like I hadn’t expected. Many of the basic features of this game are likely to be hear much sooner than I ever anticipated. Once I have gotten Chemaria to a point where I am comfortable letting the general public mess around with it, i intend to throw it onto Steam DIrect and at that point, fork off of my public repo and make the forked project private. This way anyone who wants to see how I implemented the base game will have full access to the initial codebase, while still preserving my intellectual privacy moving forward. In the end, I want this game to not only succeed in fulfilling my vision, but also provide a good point for others to start from and reference for their various questions or needs.
The ability to pick up items is in the game! I implemented max stack sizes per item, so when you attempt to pick up an item, it tries to find the first spot of the same type with less than the max stack size. If it first finds an empty spot, it will fill it in. As of right now, it is a very naive approach, so it simply reads through the toolbar and then the inventory and places the block in the first valid spot it finds.
Likely in the future I will change it to place it into the first spot of the same type with less than max stack, and if it cannot find a spot, place it into an empty spot.
What is next?
I am likely going to be working on more of the logic for world rendering and loading. Currently, the whole world is instantiated at the same time, including all of the game objects. I will be implementing dynamic loading and unloading of world chunks. Likely, this is going to be a very complicated problem compared to most everything else that has been implemented so far in Chemaria, but I feel comfortable with the foundation at this point to begin messing with how this is done.
I decided early on that I did not want to work on loading and unloading until after I figured out how the player should be interacting with the world itself and we are at that point! All other features that I deem necessary before release are more peripheral or more UI-based, so it does not relate to the world loading and can be tabled for now.
Benefits of the Dev Diary
This dev diary has really helped organize my thoughts and priorities through making this game. It also has given me a checkpoint at the end of each feature I am excited for: letting everyone know where I am and hopefully encouraging other blossoming game devs to follow their aspirations, instead of sitting back and saying, “This would be nice some day but I can’t [insert fake excuse here]” as I did for so long.
The world now only loads within a set distance around the player! This allows Chemaria to have arbitrarily large worlds but only load and render a subset of game objects at any given time.
This was a bit interesting to implement. I ended up resorting to some good old-fashioned set arithmetic to find what chunks must be deleted based on what chunk the player moved into, compared to the chunk they inhabited before.
What is next?
At this point, I will be working on getting a basic crafting system in. At least initially, I will be taking a lot of inspiration from how Terraria does it, where you are simply presented with the options of what can be made with what you have, but I will be adding my own flavor to it of course.
After crafting is implemented, I will be spending much more time on the visuals of the game:
- Block and Item Sprites
- World Background
- Character Sprite and movement animations
I am also running into an issue with saving large worlds to a file but, as I have mentioned before, I have submitted a Github issue on that matter and I have a workaround in mind if a fix is not made in time.