Idle Game Electronjs project example - MrSun Idle prototype
When it comes to my collection of electronjs examples thus far I do not have an example that is some kind of game project, so I have started one project that is a kind of Idle Game. The game prototype idea is called MrSun, and the general idea is to have a single object that is a sun, and a bunch of objects around the sun that are land sections. Each land section is then composed of a grid of slots, each of which can contain a block that will generate the main game currently which in this case is mana.
The sun can then be moved into other locations in the area between all the land section objects. When doing so the distance from the sun to each land section object will change which will result in temperature changes for each land section. The changes in temperature will then effect the rate at which mana for each block in a given land section is. That is that I have a base mana amount, and a temperature mana amount that together compose the total mana delta amount for each block in each slot in each land section.
I have made a whole lot of game prototypes in the past when it comes to my collection of html canvas examples, but this time around with my electronjs examples I would like to focus more so on quality rather than quantity. For this game prototype I have stayed in my lane for the good part of a month, and on top of that I have plans to continue working on this project in a stand alone repository as well. So then this will not just be yet another prototype but a game that I will keep working on, and playing myself, for a little while every day.
What I have in mind here then is not just another idle game, but a game that also pulls in elements of strategy, simulation, and sandbox type games. The core features of an idle game are there is the prototype all ready, and as I keep working on this as a stand alone project I will be seeking to further refine the features in place as well as take additional steps with various other ideas that I think will add more value to this project.
The MrSun Idle Game Prototype and what to know first
In this post I am writing about a electronjs project example that is my first electronjs game project that is an example of an idle game project. I really went off the deep end with this one when it comes to the client system which is composed of many modules of my own design. I did not write all of them from the ground up though, many are based on source code examples that I have started for many other projects, others are hacked over threejs source code files. I have also borrowed code from a few other projects as well, and it would look like I will need to release any final product based on this under the MIT License because of it. In any case this is not a post for people that are new to using electronjs
The full up to date source code for the prototype can be found on Github
The best way to get things up and running with the prototype that I am writing about in this post might be to clone down my elecitonjs examples repo and then do an npm install for the electronjs-example-mrsun project in the for post folder. This will install the version of electronjs I was using and as of this writing that is the only npm package that is being used for this one.
Version Numbers
When I wrote this blog post I was writing about R86 of my MrSun Idle Electionjs Example. Sense the writing of this post it is likley that I have made at least a few more revisions of the example, and have not got around to editing this post just yet. Also I might have started a whole other project based off of this source code as well.
1 - electronjs Files
As with just about any electronjs project there are two general things to write about, electronjs code and the client system code. In this section I am going to be writing about what it is that I have in place when it comes to the typical electronjs files such as the main.js and preload.js files. On top of those two files I also have one additional nodejs script that I should write about also while I am at it.
1.1 - The main.js file
There is not much to write about when it comes to the main.js file with this one actually. For this project I really went off the deep end when it comes to the client side code, but not so much when it comes to the front end code. So I just have a create main window helper function, a custom menu, and then a few events here.
1.2 - The preload.js file
While working on this project I ran into a problem that had to do with a race condition when saving a game state file to the file system. If a save was in progress and I quit or reloaded the game before the save was finished I would loose my save state. There might be a number of ways to go about addressing this problem but the way that I solved it was by just making use of an additional nodejs file and using the fork method of the nodejs child process module to launch a save as a whole other detached process on the client system. This way the detached process will continue even if the main game process was killed, or the game was reloaded.
1.3 - The save file script savefile.js
As I have covered in the section on the preload.js file for this game prototype. Nothing major with this script as it just needs to be a very basic script that will just write a file using the write file method of the nodejs file system module.
2 - The Client system
Now that I have covered all the code that has to do with the electronjs files there is now going over all the code that has to do with the client system for this game. This is where things get a little involved with this as I worked on this game prototype a little each day for the good part of a month. There are a lot of javaScript modules that compose the game code thus far then. The onces that I have not done much with I will just write about and link to where you can see the copies of the modules that I am using in the github project folder. Others I have hacked over a lot, or have wrote from the ground up and as such I might post the code here then.
3 - Using a copy of Decimal.js for high percision math
I have went with decimal.js as a module for working with very big numbers. If you have coded with javaScript as long as I have then chances are I do not need to lecture you as to why it is a good idea to use a library like this when making any kind of project that involves working with very big numbers which is often the case with idle games. If not then there is reading up more on what max safe integer is to get an idea with what the limits are with regular javaScript numbers. A possible native alternative to bothering with a user space module would be to use big integers, however I find them lacking when it comes to math methods.
4 - Using event-dispatcher from threejs
I am using the event-dispatcher source code files from the threejs project. I have decided to make this a 2d game, but I have found that I would still like to use some features from threejs by just making use of some of the source code files. The event dispatcher in threejs is a way to go about creating custom user space events for plain old javaScript objects rather that elements. I am using this to create events for my main game object.
5 - Using lz-string to compress save state data
I have went with lz-string to compress save state data. For this project I have made a custom hack job of the file in order to turn it into a javaScript module, and while I was at it I removed all the code that I was not using.
6 - A hacked over THREEJS Vector2 Class
I made a copy of the Vector2 class and hacked over it a little. One major change that I made has to do with the methods for getting angles between two points as I have found that the angle to method that comes with the class is not working the way that I would like it to. I thus went with an angle to method that is just an abstraction for the usual deal with the Math.atan2 method that is often what will be used for this kind of task in some way. The angle to method in the threejs vector2 class also makes use of a single method in that math utils object, so the options are then to add the whole math utils module also, copy over the source code for this single method, or just start removing code that I am not using from this custom cut Vector2 class module.
|
|
7 - Object2d
I started an Object2d class which I would like to make like that of the Object3d class in threejs. Maybe not so much in this prototype, but as I start to work on a final game based off of this I am sure I will expand on this class a whole lot.
|
|
8 - Object2d-sprite
For this prototype thus far I have one additional module in which I extend from my base object2d class that is a sprite class.
|
|
9 - Canvas
I started a custom canvas module for this game based on what I made for my blog post on canvas textures in threejs. I removed a lot of the built in draw functions that I will not be using in this project, and also turned it into a javaScript module rather than the IIFE format that is was in.
|
|
10 - Mrsun-constant
When I first started working on this I ended up with a lot of constant values up at the top of my main game state module. I then ran into a situation in which I need to get at these constant values from one of my other modules that has to do with the state machine or some render function. So I have found that it might just be best to have some kind of main module that is just one big collection of constant values that are used in the game state, as well as all over the program in general. I then import this module in my game module, and then everywhere else where I would need to do so as well.
|
|
11 - mrsun-game
I have a folder that contains that main game state module, as well as a number of other supporting files for this. The main game module create method is what I call to create a main game state object. I then have also took code that has to do with the state of the sun object, as well as the land objects broken down into other files.
11.1 - The sun module
This module contains that main sun class which I use to create the object the stores the current position of the sun. I also have a number of methods in this class that have to do with updating the animation state of the sun, as well as the position of the sun relative to a fixed center position.
|
|
11.2 - The Land Module
The land module then contains mostly of the code that I use to create an update the various objects that compose a land section object as well as the whole collection of these land section objects, and also the various slots of each land section as well. So there is then a main Land class, then a LandSection class, Slot class, and then a Block class.
|
|
11.3 - The game module
The main game module then makes use of the sun and land modules as well as the constant module and is thus what I use to create a game state object as well as update it over time. There is the main create method that I call in the init state, and then also with a supernova event in my supernova state. More on all of this in my section on the state machine.
|
|
12 - Mrsun-statemachine
One major component of a game, or most applications in general is to have something to serve as a state machine. Simply put there is not just having a single update method called in a loop, but rather a collection of update methods to which only a single one is called at any given moment. While we are at it there is also not just having a collection of update methods but also input event handers, render functions, and additional hook functions also. In MrSun I have a main state machine module, and then also a collection of state objects for several states of the over all game.
12.1 - The Main state machine module
This is what I have together for my main state machine module for the game. This then contains that main update loop for the over all game, as well as the various functions that compose what the uniform logic is that will apply to all state objects. Speaking of the state objects I thus far have an init state, world state, and a supernova state that is the start of the Prestige mechanic of this idle game.
|
|
12.2 - The init state
The init state is what will be used just once when the game starts up for the very first time. In this state I do things like check if there is a save state, and if not start a new game. Once the init state is done with what it needs to do I then just start the main world state.
|
|
12.3 - The world state
The world state is where I can change the position of the sun relative to the other land sections objects that are around it. It is also where I can get an over all view of each land state object, but in order to do anything with a given land state object I must switch to the land state.
|
|
12.4 - The land state
The land state is where I can get into the world building aspect of this game that I have in mind. Here I can unlock slot objects, and when doing so I can create or absorb a rock type block. These blocks are then what will generate mana which is the main currency of interest in this. The rate at which mana is gained is then impacted by the position of the sun with respect to a temperature mana gain value.
|
|
12.5 - The super nova state ( Prestige mechanic )
A common mechanic to have in idle games is something that is often referred to as a Prestige mechanic. For my Mr Sun electronjs example prototype I am calling this kind of mechanic a supernova event which just strikes me as a good name for it with respect to the over all theme of this project.
|
|
13 - mrsun-utils
I have a general utilities module which is where I just pack all kinds of methods that I might use more than once across a bunch of files, but can not think of any other place to park it. Seems that lots of popular libraries have a module such as this that is just a function junk drawer.
|
|
14 - main electronjs
I then just have one main module where I create a main state machine object, and then just start that object once I have that. For now with this prototype I just have this working as an Electronjs application. However when I do start to work on the final project of this I am going to want to at least have a Browser version of the game as well. This is why I pass a PLATFROM option when calling the main state machine create method. For electronjs this is the API that I define in my preload.js file, but with a Browser version I am going to what to have another platform that will be a pure web only version of that API.
I can also if need be make more that one preload.js file if need be for certain Operating systems that might prove to be problematic allowing me to make one that will work well with that platform without breaking something that works fine for others.
|
|
Conclusion
So that is the general overview for this electronjs project example of an idle game. I really put a whole lot of time into this one so it is safe to say that I will be treating this example the same way as I have with my video creation tool project example. Simply put this means that it is going to get its own repo and I am going to containing working on it a little more now and then which is not always the case with some of these electronjs example projects that I have made thus far. Many of them are just prototypes, but some of them I continue working on if they are software tools that I use everyday, or enough people start to show interest. This game might prove to be one of those projects as I find myself getting addicted to my own game Tony Montana style.