Mr Sun Geo.js and additional plug-ins

Today I started yet another canvas example based off the Mr Sun source code that I started recently. This time I started out with the source code, and plug-ins that I worked out for my Mr Sun Temp example. So when Mr Sun Geo as I have come to call it thus far is yet even more on top of that example.

In the previous fork Mr Sun Temp I made just a few minor improvements to the source code itself, and the real additions where in the form of a few plug-ins. The main focus there was the temp.js plug-in for this project that just contained the logic that sets temperature for the sun object, and all the world section objects. In this fork I am focusing on creating additional plug-ins that will have to do with the Geology, the Hydrosphere, and Atmosphere of the Game World in what I am just calling Mr Sun. All of these plug-ins depend on the previous plug-ins worked out in Mr Sun Temp, when it comes to temp.js and also fusion.js.

So then Mr Sun Geo is just the next step forward when it comes to working out game logic that will create a cool little simulated world.

1 - The geo.js plug-in

The very first version of Mr Sun Geo is just the addition of one plug-in on top of what I worked out in Mr Sun Temp 0.5.0. Geo stands for Geology, and as such this plug-in adds properties such as magmatism, and elevation to the game world section objects.

The plug-in alone proved to be a little time consuming just to get some of the basics worked out with how the position of the sun object effects the increase of elevation. Values that are added in by way of the temp.js plug-in are used to set magmatimsm, and magmatism is used to find the rate at which elevation will go up for each game year. There is also an erosion property that is part of this module, the additional plug-ins that have to do with the hydrosphere, and the atmosphere will have will have an impact on that value.

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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
// geo.js plug-in
gameMod.load((function () {
// tabulate the mass of an object
var tabulateObjectMass = function (obj) {
var i = 0,
len = Object.keys(obj.minerals).length,
minKey,
min,
mass = 0;
while (i < len) {
minKey = Object.keys(obj.minerals)[i];
min = obj.minerals[minKey];
mass += min;
i += 1;
}
return mass;
};
// set total mass by tabulating all sections
var setTotalMass = function (game) {
var gd = game.geoData,
i = 0,
len = game.sections.length,
mass,
section;
gd.totalMass = 0;
while (i < len) {
section = game.sections[i];
section.totalMass = tabulateObjectMass(section);
gd.totalMass += section.totalMass;
i += 1;
}
};
// set massPer prop for all sections
var updateSectionValues = function (game, deltaYears) {
var gd = game.geoData,
i = 0,
len = game.sections.length,
mass,
section;
while (i < len) {
section = game.sections[i];
section.massPer = 0;
if (section.totalMass > 0) {
// set mass percentage
section.massPer = section.totalMass / gd.totalMass;
// set magmatism
section.magmatism = section.massPer * (section.groundTemp / game.tempData.globalMaxGroundTemp);
// elevation
section.elevation = section.elevation + section.magmatism * deltaYears * gd.maxElevationPerYear;
section.elevation = section.elevation - section.erosion * deltaYears * gd.maxErosionPerYear;
section.elevation = section.elevation > gd.maxElevation ? gd.maxElevation: section.elevation;
section.elevation = section.elevation < 0 ? 0: section.elevation;
}
i += 1;
}
};
return {
name: 'geo',
callPriority: '2',
create: function (game, opt) {
game.geoData = {
totalMass: 0,
maxElevation: 1000,
maxElevationPerYear: 10,
maxErosionPerYear: 1,
seaLevel: 0
};
var gd = game.geoData;
game.sections.forEach(function(section){
section.totalMass = 0;
section.massPer = 0;
section.magmatism = 0;
section.erosion = 0.5;
section.elevation = 0;
});
},
onDeltaYear: function (game, deltaYears) {
setTotalMass(game);
updateSectionValues(game, deltaYears);
}
};
}
()));

There is much more that comes to mind when it comes to what should be part of this module, however for now one of the basic features that I had in mind is indeed working. In time the code here will likely change a lot, but in any case I am going to want some code that will effect elevation of the game world sections.

2 - The hydo.js plug-in

Another addition in terms of plug-ins here is the introduction of a plug in that will handle aspects of the hydosphere of the game world. For now as of 0.3.0 at least this hydo.js plug-in will just define the total amount of game water to work with, and how it will transfer from one section to another. For the most part this is just an exercise of a plug-in working on top of another plug-in which in this case is geo.js.

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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
// hydro.js plug-in
gameMod.load((function () {
// distribute total water to world sections
var distributeWater = function(game){
var hd = game.hydroData;
var perSection = Math.floor(hd.water.total / game.sections.length),
oddWater = hd.water.total % game.sections.length;
game.sections.forEach(function(section){
section.water.amount = perSection;
});
game.sections[0].water.amount += oddWater;
};
// transfer water from one section to another based on elevation
var transferElevation = function(game, section){
var len = game.sections.length;
var n1 = game.sections[utils.mod(section.i - 1, len)];
var n2 = game.sections[utils.mod(section.i + 1, len)];
if(section.elevation.total + section.water.amount > (n1.elevation.total + n1.water.amount) && section.water.amount >= 1){
section.water.amount -= 1;
n1.water.amount += 1;
}
if(section.elevation.total + section.water.amount > (n2.elevation.total + n2.water.amount) && section.water.amount >= 1){
section.water.amount -= 1;
n2.water.amount += 1;
}
};
var updateSectionValues = function (game, deltaYears) {
var hd = game.hydroData,
i = 0,
len = game.sections.length,
section;
while (i < len) {
section = game.sections[i];
// transfer water by elevation
transferElevation(game, section);
// set evaporation
section.water.evaporation = section.temp / 100;
section.water.evaporation = section.water.evaporation > 1 ? 1 : section.water.evaporation;
// water per
section.water.per = section.water.amount / hd.water.total;
i += 1;
}
};
// plugObj for hydro.js
return {
name: 'hydro',
callPriority: '2.1',
create: function (game, opt) {
console.log(this.name);
// create hydroData Object
game.hydroData = {
water:{
total : 1000
}
};
// set defaults for section.water
game.sections.forEach(function(section){
section.water = {
amount: 0,
evaporation: 0,
per: 0
};
});
distributeWater(game);
},
onDeltaYear: function (game, deltaYears) {
updateSectionValues(game, deltaYears);
}
};
}
()));

3 - The atmo.js plug-in for a starting plug-in that has to do with the atmosphere.

There is now a geo.js plug-in that has to do with increases in elevation, and a hydo.js that has to do with water, bit that brings up the question of evaporation and rain. Should that all be part of hydro.js, or should it be part of another plug-in that has to do with the atmosphere? In any case I am going to want a plug-in that has to do with the creating and updating of state that has to do with the atmosphere of the game world.

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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
// atmo.js plug-in
gameMod.load((function () {
// evaporation
var evaporation = function (section) {
// transfer water from water object to atmo object
if (section.water.evaporation > 0.10 && section.water.amount >= 1) {
section.atmo.water.amount += 1;
section.water.amount -= 1;
}
};
// transfer water between atmo objects
var transferAtmo = function (game, section) {
var len = game.sections.length,
n1 = game.sections[utils.mod(section.i - 1, len)],
n2 = game.sections[utils.mod(section.i + 1, len)];
if (section.atmo.water.amount > n1.atmo.water.amount && section.atmo.water.amount >= 1) {
section.atmo.water.amount -= 1;
n1.atmo.water.amount += 1;
}
if (section.atmo.water.amount > n2.atmo.water.amount && section.atmo.water.amount >= 1) {
section.atmo.water.amount -= 1;
n2.atmo.water.amount += 1;
}
};
// rain water down back to the section water object
var rain = function (game, section) {
var roll = Math.random(),
delta,
secAtmo = section.atmo;
if (secAtmo.water.rainCount <= 0) {
if (roll < secAtmo.water.rainPer) {
//secAtmo.water.rainCount = 2;
secAtmo.water.rainCount = Math.round(game.atmoData.rainCountMax * Math.random());
}
}
if (secAtmo.water.amount >= 1 && secAtmo.water.rainCount > 0) {
delta = Math.floor(secAtmo.water.amount * game.atmoData.maxWaterPercent);
delta = delta > 1 ? delta : 1;
secAtmo.water.amount -= delta;
section.water.amount += delta;
secAtmo.water.rainCount -= 1;
}
};
// set per values
var setPerValues = function (game) {
var highAtmoWaterAmount = Math.max.apply(null, game.sections.map(function (section) {
return section.atmo.water.amount;
}));
game.sections.forEach(function (section) {
section.atmo.water.per = section.atmo.water.amount / (highAtmoWaterAmount || 1);
});
};
// update section objects
var updateSectionValues = function (game, deltaYears) {
var hd = game.hydroData,
i = 0,
len = game.sections.length,
section;
while (i < len) {
section = game.sections[i];
// water evaporation, transfer, and rain
evaporation(section);
transferAtmo(game, section);
rain(game, section);
i += 1;
}
setPerValues(game);
};
// plugObj for hydro.js
return {
name: 'atmo',
callPriority: '2.2',
create: function (game, opt) {
console.log(this.name);
// create hydroData Object
game.atmoData = {
rainCountMax: 10,
maxWaterPercent: 0.20 // percentage of water per rainCount
};
// set defaults for section.water
game.sections.forEach(function (section) {
section.atmo = {
water: {
//rain: false,
rainPer: 0.05,
rainCount: 0,
amount: 0,
per: 0
}
};
});
},
onDeltaYear: function (game, deltaYears) {
updateSectionValues(game, deltaYears);
}
};
}
()));

4 - Conclusion

So far I am happy with how this project is coming along, but there is still much more work ended until this will start to look like an actual game. I am going to want to add additional plug-ins that will have to do with life and civilization at some point, however maybe there are a few more that needed to be worked out before I get to that point.

I am going to want to add some additional plug-ins that have to do with graphics, and I might also want to return the working out what the very core of the game should be. There is much that I think still need to be worked out when it comes to game.js, and how to handle states. I think that I am going to want some additional features for plug-ins for this beyond just a simple create and update method.