Skip to content

Instantly share code, notes, and snippets.

@caramboleyo
Created December 20, 2022 19:39
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save caramboleyo/0577d30d1b9d7c579ca2af52b17e3e09 to your computer and use it in GitHub Desktop.
Save caramboleyo/0577d30d1b9d7c579ca2af52b17e3e09 to your computer and use it in GitHub Desktop.
import { planetHexasphere } from '../client/hexasphere.js';
import PlanetGenerator from '../client/planet-generator.js';
import '../hybrid/helpers.js';
import { prettyUrl } from '../../../deps.js';
import { getHexagonalGeometry } from '../hybrid/coordinates.js';
class Generator {
constructor() {
return new Promise(async resolve => {
this.systemTypes = await mongoDb.collection('systemTypes').find().toArray();
this.planetTypes = await mongoDb.collection('planetTypes').find().toArray();
this.systemPossibilities = this.generateSystemPossibilities();
this.planetPossibilities = this.generatePlanetPossibilities();
//l(this);
resolve(this);
});
}
rand(min, max) {
return Math.round(Math.random() * (max - min) + min);
}
generateSystemPossibilities() {
const probabilities = [];
const systemTypes = {};
for (const systemType of this.systemTypes) {
for (let i = 0; i < systemType.probability; i++) {
probabilities.push(systemType.name);
systemTypes[systemType.name] = systemType;
}
}
this.systemTypes = systemTypes;
return probabilities;
}
generatePlanetPossibilities() {
const probabilities = [];
const planetTypes = {};
for (const planetType of this.planetTypes) {
for (let i = 0; i < planetType.probability; i++) {
probabilities.push(planetType.name);
planetTypes[planetType.name] = planetType;
}
}
this.planetTypes = planetTypes;
return probabilities;
}
async generate() {
await mongoDb.drop('users');
await mongoDb.drop('nations');
await mongoDb.drop('spaceTiles');
await mongoDb.drop('planets');
await mongoDb.drop('planetTiles');
await mongoDb.drop('settlements');
await mongoDb.collection('spaceTiles').createIndexes({
indexes: [/*{
name: 'uniqueXY',
key: { coordinates: },
unique: 1,
}, */{
name: 'geo2d',
key: { coordinates: '2d' },
unique: 1,
min: -999999,
max: 999999,
}]
});
// Miserit Anhtar System
const system = {
coordinates: [0, 0],
type: 'BLUE',
name: 'Miserit Anthar'
};
system.url = prettyUrl(system.name);
const systemId = await mongoDb.collection('spaceTiles').insertOne(system);
let planet;
let distanceToSun = 10;
distanceToSun += this.rand(3, 5);
planet = {
index: 0,
systemId,
size: 4, //size
type: 'LAVA', //type
name: 'Lavara', //name
rotationSpeed: -0.015, //rotation speed positive is clockwise
distanceToSun, // distance from center of the sun,
orbitSpeed: 150, // orbit speed
//i: Date.now(), // last time position was at null degrees
};
planet.url = prettyUrl(planet.name);
planet._id = await mongoDb.collection('planets').insertOne(planet);
this.generatePlanetTiles(planet);
distanceToSun += this.rand(3, 5);
planet = {
index: 1,
systemId,
size: 5, //size
type: 'DESERT', //type
name: 'Hasaroh', //name
rotationSpeed: -0.015, //rotation speed positive is clockwise
distanceToSun, // distance from center of the sun,
orbitSpeed: 100, // orbit speed
//i: Date.now(), // last time position was at null degrees
};
planet.url = prettyUrl(planet.name);
planet._id = await mongoDb.collection('planets').insertOne(planet);
this.generatePlanetTiles(planet);
distanceToSun += this.rand(3, 5);
planet = {
index: 2,
systemId,
size: 7,
type: 'BARREN',
name: 'Roxan',
rotationSpeed: -0.015, //rotation speed positive is clockwise
distanceToSun, // distance from center of the sun,
orbitSpeed: 200, // orbit speed
//i: Date.now(), // last time position was at null degrees
};
planet.url = prettyUrl(planet.name);
planet._id = await mongoDb.collection('planets').insertOne(planet);
this.generatePlanetTiles(planet);
distanceToSun += this.rand(3, 5);
planet = {
index: 3,
systemId,
size: 18,
type: 'EARTHLIKE',
name: 'Miserit',
rotationSpeed: -0.015, //rotation speed positive is clockwise
distanceToSun, // distance from center of the sun,
orbitSpeed: 300, // orbit speed
//i: Date.now(), // last time position was at null degrees
};
planet.url = prettyUrl(planet.name);
planet._id = await mongoDb.collection('planets').insertOne(planet);
this.generatePlanetTiles(planet);
distanceToSun += this.rand(3, 5);
planet = {
index: 4,
systemId,
size: 20,
type: 'EARTHLIKE',
name: 'Anthar',
rotationSpeed: -0.015, //rotation speed positive is clockwise
distanceToSun, // distance from center of the sun,
orbitSpeed: 400, // orbit speed
//i: Date.now(), // last time position was at null degrees
};
planet.url = prettyUrl(planet.name);
planet._id = await mongoDb.collection('planets').insertOne(planet);
this.generatePlanetTiles(planet);
distanceToSun += this.rand(3, 5);
planet = {
index: 5,
systemId,
size: 20,
type: 'GAS',
name: 'Gosa',
rotationSpeed: -0.015, //rotation speed positive is clockwise
distanceToSun, // distance from center of the sun,
orbitSpeed: 500, // orbit speed
//i: Date.now(), // last time position was at null degrees
};
planet.url = prettyUrl(planet.name);
planet._id = await mongoDb.collection('planets').insertOne(planet);
this.generatePlanetTiles(planet);
const circleStart = 1;
const circleEnd = 20;
for (let circle = circleStart; circle <= circleEnd; circle++) {
const tilesInCurrentCircle = this.generateCircle(circle, 0, 0);
for (const tile of tilesInCurrentCircle) {
await this.generateTile(tile[0], tile[1]);
}
}
}
generateCircle(r, x = 0, y = 0) {
return tileRing(r, x, y);
}
async generateTile(x, y) {
let stop = false;
// step1: check if there is no other solar system in the surrounding tiles
const neighbors = [
...this.generateCircle(1, x, y), // tile around
...this.generateCircle(2, x, y) // two tiles around
];
//l('>>>neighbors', x, y, neighbors);
const tiles = await mongoDb.collection('spaceTiles').find({ coordinates: { $in: neighbors } }).toArray();
//l('>>>neighbors', neighbors, tiles);
for (const neighbor of tiles) {
if (neighbor.type) {
stop = true;
break;
}
}
// step2: Decide randomly if current tile gets a solar system
if (!stop) {
const random = [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0];
const r = this.rand(0, 10);
//l('>>>dice', r);
if (random[r]) {
await this.generateSolarSystem(x, y);
} else {
stop = true;
}
}
if (stop) {
await mongoDb.collection('spaceTiles').insertOne({
coordinates: [x, y],
});
//l(`created (${x}|${y})</b> space`);
}
}
async generateSolarSystem(x, y) {
const type = this.getRandomSystemType();
const name = await this.generateName();
const system = {
coordinates: [x, y],
type,
name
};
system.url = prettyUrl(system.name);
const systemId = await mongoDb.collection('spaceTiles').insertOne(system);
l(`created (${x}|${y}) system ${name} of type ${type}`);
// Decide how many planets current solar system has
const planets = this.rand(0, this.systemTypes[type].planets);
let distanceToSun = 10;
// Decide what size and type those planets are
for (let i = 0; i < planets; i++) {
distanceToSun += this.rand(3, 5);
if (distanceToSun > 85) {
break;
}
let type = this.getRandomPlanetType();
const size = this.rand(type.min_size, type.max_size);
const planetName = name + ' ' + (i + 1);
const planet = {
index: i,
systemId,
size,
type: type.name,
name: planetName,
distanceToSun,
orbitSpeed: this.rand(50, 950),
rotationSpeed: this.rand(.01, .05),
};
planet.url = prettyUrl(planet.name);
// has rings
if (this.rand(0, 9) > 4) {
planet.rings = {
radius: this.rand(-Math.PI, Math.PI),
width: this.rand(2, 20)
};
}
planet._id = await mongoDb.collection('planets').insertOne(planet);
this.generatePlanetTiles(planet);
}
}
async generatePlanetTiles(planet) {
const tiles = [];
const hexasphere = planetHexasphere(planet);
const pg = new PlanetGenerator(hexasphere, planet);
for (const index in pg.hexasphere.tiles) {
const tile = pg.hexasphere.tiles[index];
const n = tile.neighbors.map(n => n.index);
const newTile = {
planetId: planet._id,
index: Number(index), // index
type: tile.t, // type
height: tile.h, // height
forest: tile.f, // forest
resources: tile.resources,
neighbors: n, // neighbors
center: {
x: tile.centerPoint.x,
y: tile.centerPoint.y,
z: tile.centerPoint.z,
},
}
tiles.push(newTile);
}
await mongoDb.collection('planetTiles').insertMany(tiles);
}
getRandomSystemType() {
return this.systemPossibilities[this.rand(0, this.systemPossibilities.length - 1)];
}
async generateName() {
let name = [];
const vocals = ['a', 'e', 'i', 'o', 'u'];
const consonants = ['b', 'c', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'm', 'n', 'p', 'q', 'r', 's', 't', 'v', 'w', 'x', 'y', 'z'];
const words = this.rand(1, 3);
for (let w = 0; w < words; w++) {
let word = '';
const letters = this.rand(3, 5);
for (let l = 0; l < letters; l++) {
if (l % 2) {
word += vocals[this.rand(0, 4)];
} else {
word += consonants[this.rand(0, 20)];
}
}
name.push(word);
}
for (const key in name) {
name[key] = name[key][0].toUpperCase() + name[key].slice(1);
}
name = name.join(' ', name);
const check1 = await mongoDb.collection('tiles').find({ name }).toArray();
const check2 = await mongoDb.collection('planets').find({ name }).toArray();
if (check1.length === 0 && check2.length === 0) {
return name;
} else {
return this.generateName();
}
}
getRandomPlanetType() {
return this.planetTypes[this.planetPossibilities[this.rand(0, this.planetPossibilities.length - 1)]];
}
}
self.Generator = Generator;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment