Compare commits

..

7 Commits

Author SHA1 Message Date
Valerie 5482803bbe mostly fonts lawl 2021-07-30 22:11:13 -04:00
Valerie 2dc1c6b8d8 split up qt widgets! 2021-07-29 15:32:30 -04:00
Valerie cbc45c1aef debug page 2021-07-29 13:28:30 -04:00
Valerie 8f4d21c00d reworked ticking for many configs! maybe in settings?! 2021-07-29 12:51:31 -04:00
Valerie 845cb376e8 deployment stuff, kindof 2021-07-28 23:18:03 -04:00
Bronwen 0015ccae43 timeControl! 2021-07-28 23:08:45 -04:00
Valerie 69f79d0761 multiplayer! 2021-07-28 01:42:32 -04:00
388 changed files with 662 additions and 288 deletions

3
.gitignore vendored
View File

@ -3,3 +3,6 @@ out
data data
*.log *.log
bin bin
deploy/win32/build
*-v*.*.*.tgz
dist

View File

@ -0,0 +1 @@
{"appName":"Hadean"}

View File

@ -0,0 +1,3 @@
{
"distPath": ".\\dist"
}

View File

@ -1,6 +1,6 @@
{ {
"name": "hadean", "name": "hadean",
"version": "1.0.0", "version": "0.0.1",
"main": "index.js", "main": "index.js",
"license": "MIT", "license": "MIT",
"type": "module", "type": "module",
@ -8,6 +8,7 @@
"@babel/core": "^7.14.8", "@babel/core": "^7.14.8",
"@babel/preset-env": "^7.14.8", "@babel/preset-env": "^7.14.8",
"@nodegui/nodegui": "^0.34.0", "@nodegui/nodegui": "^0.34.0",
"@nodegui/packer": "^1.4.1",
"@rollup/plugin-alias": "^3.1.4", "@rollup/plugin-alias": "^3.1.4",
"@rollup/plugin-babel": "^5.3.0", "@rollup/plugin-babel": "^5.3.0",
"@rollup/plugin-json": "^4.1.0", "@rollup/plugin-json": "^4.1.0",
@ -64,6 +65,8 @@
"tsc": "tsc", "tsc": "tsc",
"tsc:watch": "yarn tsc --watch", "tsc:watch": "yarn tsc --watch",
"rollup": "rollup --config rollup.config.js", "rollup": "rollup --config rollup.config.js",
"rollup:watch": "yarn rollup --watch" "rollup:watch": "yarn rollup --watch",
"poop": "rollup --config rollup.prod.config.js && nodegui-packer --pack ./dist && \".\\deploy\\win32\\build\\Hadean\\qode.exe\"",
"build": "nodegui-packer --pack ./dist"
} }
} }

View File

@ -0,0 +1,7 @@
import configs from './rollup.config.js';
const appBundleConfig = configs[0];
appBundleConfig.output.file = 'dist/index.js';
appBundleConfig.output.format = 'es';
export default [
appBundleConfig
];

View File

@ -1,10 +1,27 @@
export const IPC_PATH = '/tmp/dfi.dev'; import { parse, resolve } from 'path';
export const IPC_CLIENT_APPSAPCE = 'dfi.'; import { fileURLToPath } from 'url';
// === [ app info ] ===
export const APPLICATION_NAME = 'Hadean';
export const INSTALL_LOCATION = resolve(parse(fileURLToPath(import.meta.url)).dir);
// === [ netowkring ] ===
export const MDNS_TYPE = 'hdn';
// === [ IPC DEV SERVER ] ===
export const IPC_CLIENT_CONNECT_NAME = 'dev'; export const IPC_CLIENT_CONNECT_NAME = 'dev';
export const IPC_CLIENT_APPSPACE = MDNS_TYPE + '.';
export const IPC_PATH = '/tmp/' + IPC_CLIENT_APPSPACE + IPC_CLIENT_CONNECT_NAME;
export const IPC_QUIT_EVENT = 'app.quit'; export const IPC_QUIT_EVENT = 'app.quit';
export const IPC_RESTART_EVENT = 'app.restart'; export const IPC_RESTART_EVENT = 'app.restart';
export const IPC_REQUEST_RESTART = 'app.request-restart'; export const IPC_REQUEST_RESTART = 'app.request-restart';
export const MDNS_TYPE = 'hdn'; // === [ styling ] ===
export const FONT_FAMILY = 'MxPlus IBM VGA 8x14'
export const APPLICATION_NAME = 'Hadean' export const FONT_LOCATION = resolve(
INSTALL_LOCATION,
'assets/font/bitmap',
FONT_FAMILY.replace(' ', '_') + '.ttf'
);
export const FONT_SIZE = 12;

View File

@ -24,9 +24,9 @@ export class Game extends Frigid implements Tickable {
return game; return game;
} }
async tick() { async tick(seconds: number) {
for(const pawn of this.pawns) { for(const pawn of this.pawns) {
pawn.tick(); pawn.tick(seconds);
} }
update(); update();
} }
@ -62,7 +62,6 @@ export class Game extends Frigid implements Tickable {
this.inventory.validate(); this.inventory.validate();
this.clock ??= new Time(); this.clock ??= new Time();
this.clock.start(this); this.clock.start(this);
this.pawns = [];
if(this.pawns.length === 0) { if(this.pawns.length === 0) {
for(let i = 0; i < 3; i ++) this.pawns.push(new Pawn()); for(let i = 0; i < 3; i ++) this.pawns.push(new Pawn());
} }

View File

@ -20,8 +20,8 @@ export class Pawn extends Serializable implements Tickable {
job: TaskState<unknown, unknown>; job: TaskState<unknown, unknown>;
async tick() { async tick(seconds: number) {
this.age ++; this.age += seconds;
} }
get idle() { get idle() {

View File

@ -3,13 +3,15 @@ import EventEmitter from 'events';
import ipc from 'node-ipc'; import ipc from 'node-ipc';
import { import {
IPC_CLIENT_CONNECT_NAME, IPC_CLIENT_CONNECT_NAME,
IPC_CLIENT_APPSAPCE, IPC_CLIENT_APPSPACE,
IPC_QUIT_EVENT, IPC_QUIT_EVENT,
IPC_RESTART_EVENT, IPC_RESTART_EVENT,
IPC_REQUEST_RESTART IPC_REQUEST_RESTART
} from './Constants.js'; } from './Constants.js';
let connected = false; ipc.config.appspace = IPC_CLIENT_APPSPACE;
ipc.config.silent = true;
const oldConsoleLog = console.log; const oldConsoleLog = console.log;
const patchLog = () => console.log = console.log.bind(console, chalk.cyan('[CLIENT]')); const patchLog = () => console.log = console.log.bind(console, chalk.cyan('[CLIENT]'));
@ -18,50 +20,71 @@ const restoreLog = () => console.log = oldConsoleLog;
// const log = (...args: any[]) => console.log(chalk.cyan('[CLIENT]'), ...args); // const log = (...args: any[]) => console.log(chalk.cyan('[CLIENT]'), ...args);
class ProcessManagerClass extends EventEmitter { class ProcessManagerClass extends EventEmitter {
processLock = Promise.resolve();
// TODO replace this with an async sortof
// event emitter, to wait for all clean up
connected = false;
constructor() {
super();
ipc.connectTo(IPC_CLIENT_CONNECT_NAME, () => {
ipc.of[IPC_CLIENT_CONNECT_NAME].on('connect', this.onConnect.bind(this));
ipc.of[IPC_CLIENT_CONNECT_NAME].on('disconnect', this.onDisconnect.bind(this));
ipc.of[IPC_CLIENT_CONNECT_NAME].on(IPC_REQUEST_RESTART, this.onReloadRequested.bind(this));
});
}
private onReloadRequested() {
this.emit('reload');
}
private onConnect() {
this.connected = true;
this.emit('change');
patchLog();
}
private onDisconnect() {
this.connected = false;
this.emit('change');
restoreLog();
}
quit() { quit() {
this.emit('shutdown'); this.emit('shutdown');
this.processLock.then(() => {
process.exit(0); process.exit(0);
})
} }
restart() { restart() {
this.emit('shutdown'); this.emit('shutdown');
if (connected) { if (this.connected) {
ipc.of[name].emit(IPC_RESTART_EVENT); ipc.of[IPC_CLIENT_CONNECT_NAME].emit(IPC_RESTART_EVENT);
} }
setTimeout(() => { setTimeout(() => {
process.exit(0); process.exit(0);
}) })
} }
get connected() {
return connected;
}
} }
export const ProcessManager = new ProcessManagerClass(); export const ProcessManager = new ProcessManagerClass();
const name = IPC_CLIENT_CONNECT_NAME;
ipc.config.appspace = IPC_CLIENT_APPSAPCE;
ipc.config.silent = true;
ipc.connectTo(name, () => {
ipc.of[name].on('connect', () => {
connected = true;
patchLog();
});
ipc.of[name].on('disconnect', () => {
connected = false
restoreLog();
});
ipc.of[name].on(IPC_REQUEST_RESTART, () => {
console.log('received restart request');
// ProcessManager.restart();
ProcessManager.emit('reload');
})
});
process.on('SIGKILL', () => ProcessManager.quit());
process.on('SIGTERM', () => ProcessManager.quit()); process.on('SIGTERM', () => ProcessManager.quit());
process.on('SIGINT', () => ProcessManager.quit()); process.on('SIGINT', () => ProcessManager.quit());
process.on('beforeExit', () => ProcessManager.quit());
/// // HACK dumbass hack hahahah :)
if (process.platform === "win32") {
var rl = require("readline").createInterface({
input: process.stdin,
output: process.stdout
});
rl.on("SIGINT", function () {
// @ts-ignore dont know why, dont fuckin care
process.emit("SIGINT");
});
}

View File

@ -92,7 +92,7 @@ export default class Time extends Serializable {
} }
ctor() { ctor() {
this.targetTPS = 2000; this.targetTPS = 60;
this.minute ??= 0; this.minute ??= 0;
this.hour ??= 0; this.hour ??= 0;
this.day ??= 0; this.day ??= 0;
@ -201,15 +201,50 @@ export default class Time extends Serializable {
} }
} }
async execTick(seconds: number) {
const doDynamicTick = true;
if(doDynamicTick) {
if(this.thing) {
await this.thing.tick(seconds);
}
this.advanceTime(seconds);
} else {
for(let i = 0; i < seconds; i ++) {
if(this.thing) {
await this.thing.tick(1);
}
this.advanceTime(1);
}
}
}
async doTick() { async doTick() {
this.advanceTime(1); // the higher the multitick, the more lopsided
const timeout = 1000 / this.targetTPS; // ticks become in realtime, however, they rely
// const start = ms4() // on fewer setTimeouts, which helps tick scheduling
const multitick = 1;
if(multitick > 1) {
const timeout = (1000 / this.targetTPS) * multitick;
const start = ms4(); const start = ms4();
if(this.thing) {
await this.thing.tick(); for(let tickNum = 0; tickNum < multitick; tickNum ++ ) {
const seconds = 3;
this.execTick(seconds);
this.ticksInSecond ++;
const end = ms4();
if(end > this.lastTPSCheckpoint + 1000) {
this.lastTPSCheckpoint = end;
this.tps = this.ticksInSecond;
this.ticksInSecond = 0;
} }
}
const end = ms4() const end = ms4()
const elapsed = end - start; const elapsed = end - start;
const wait = timeout - elapsed; const wait = timeout - elapsed;
@ -219,6 +254,34 @@ export default class Time extends Serializable {
if(wait < 0) { if(wait < 0) {
const ticksOver = (-wait / timeout) + 1; const ticksOver = (-wait / timeout) + 1;
if(ticksOver > 1.5)
console.log(chalk.yellow('Can\'t keep up! Tick took ' + ticksOver.toFixed(2) + ' ticks (' + (timeout - wait).toFixed(4) + 'ms)'));
}
if(this.paused) return;
setTimeout(this._boundTick, normalizedWait);
} else {
// this code is from not needing a multi-tick workaround, due to scheduling.
const seconds = 3;
const timeout = 1000 / this.targetTPS;
// const start = ms4()
const start = ms4();
this.execTick(seconds);
const end = ms4()
const elapsed = end - start;
const wait = timeout - elapsed;
const normalizedWait = Math.floor(Math.max(wait, 0));
// process.stdout.write(`tick took ${elapsed} waiting ${normalizedWait}\n`);
if(wait < 0) {
const ticksOver = (-wait / timeout) + 1;
if(ticksOver > 1.5)
console.log(chalk.yellow('Can\'t keep up! Tick took ' + ticksOver.toFixed(2) + ' ticks (' + (timeout - wait).toFixed(4) + 'ms)')); console.log(chalk.yellow('Can\'t keep up! Tick took ' + ticksOver.toFixed(2) + ' ticks (' + (timeout - wait).toFixed(4) + 'ms)'));
} }
@ -232,13 +295,18 @@ export default class Time extends Serializable {
} }
if(this.paused) return; if(this.paused) return;
setTimeout(this._boundTick, normalizedWait) setTimeout(this._boundTick, normalizedWait);
}
} }
} }
export interface Tickable { export interface Tickable {
tick: () => Promise<void> tick: (seconds: number) => Promise<void>
} }
function ms4() { function ms4() {

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More