Compare commits
7 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
5482803bbe | |
|
|
2dc1c6b8d8 | |
|
|
cbc45c1aef | |
|
|
8f4d21c00d | |
|
|
845cb376e8 | |
|
|
0015ccae43 | |
|
|
69f79d0761 |
|
|
@ -3,3 +3,6 @@ out
|
|||
data
|
||||
*.log
|
||||
bin
|
||||
deploy/win32/build
|
||||
*-v*.*.*.tgz
|
||||
dist
|
||||
|
|
@ -0,0 +1 @@
|
|||
{"appName":"Hadean"}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"distPath": ".\\dist"
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "hadean",
|
||||
"version": "1.0.0",
|
||||
"version": "0.0.1",
|
||||
"main": "index.js",
|
||||
"license": "MIT",
|
||||
"type": "module",
|
||||
|
|
@ -8,6 +8,7 @@
|
|||
"@babel/core": "^7.14.8",
|
||||
"@babel/preset-env": "^7.14.8",
|
||||
"@nodegui/nodegui": "^0.34.0",
|
||||
"@nodegui/packer": "^1.4.1",
|
||||
"@rollup/plugin-alias": "^3.1.4",
|
||||
"@rollup/plugin-babel": "^5.3.0",
|
||||
"@rollup/plugin-json": "^4.1.0",
|
||||
|
|
@ -64,6 +65,8 @@
|
|||
"tsc": "tsc",
|
||||
"tsc:watch": "yarn tsc --watch",
|
||||
"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"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
];
|
||||
|
|
@ -1,10 +1,27 @@
|
|||
export const IPC_PATH = '/tmp/dfi.dev';
|
||||
export const IPC_CLIENT_APPSAPCE = 'dfi.';
|
||||
import { parse, resolve } from 'path';
|
||||
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_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_RESTART_EVENT = 'app.restart';
|
||||
export const IPC_REQUEST_RESTART = 'app.request-restart';
|
||||
|
||||
export const MDNS_TYPE = 'hdn';
|
||||
|
||||
export const APPLICATION_NAME = 'Hadean'
|
||||
// === [ styling ] ===
|
||||
export const FONT_FAMILY = 'MxPlus IBM VGA 8x14'
|
||||
export const FONT_LOCATION = resolve(
|
||||
INSTALL_LOCATION,
|
||||
'assets/font/bitmap',
|
||||
FONT_FAMILY.replace(' ', '_') + '.ttf'
|
||||
);
|
||||
export const FONT_SIZE = 12;
|
||||
|
|
@ -24,9 +24,9 @@ export class Game extends Frigid implements Tickable {
|
|||
return game;
|
||||
}
|
||||
|
||||
async tick() {
|
||||
async tick(seconds: number) {
|
||||
for(const pawn of this.pawns) {
|
||||
pawn.tick();
|
||||
pawn.tick(seconds);
|
||||
}
|
||||
update();
|
||||
}
|
||||
|
|
@ -62,7 +62,6 @@ export class Game extends Frigid implements Tickable {
|
|||
this.inventory.validate();
|
||||
this.clock ??= new Time();
|
||||
this.clock.start(this);
|
||||
this.pawns = [];
|
||||
if(this.pawns.length === 0) {
|
||||
for(let i = 0; i < 3; i ++) this.pawns.push(new Pawn());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,8 +20,8 @@ export class Pawn extends Serializable implements Tickable {
|
|||
|
||||
job: TaskState<unknown, unknown>;
|
||||
|
||||
async tick() {
|
||||
this.age ++;
|
||||
async tick(seconds: number) {
|
||||
this.age += seconds;
|
||||
}
|
||||
|
||||
get idle() {
|
||||
|
|
|
|||
|
|
@ -3,13 +3,15 @@ import EventEmitter from 'events';
|
|||
import ipc from 'node-ipc';
|
||||
import {
|
||||
IPC_CLIENT_CONNECT_NAME,
|
||||
IPC_CLIENT_APPSAPCE,
|
||||
IPC_CLIENT_APPSPACE,
|
||||
IPC_QUIT_EVENT,
|
||||
IPC_RESTART_EVENT,
|
||||
IPC_REQUEST_RESTART
|
||||
} from './Constants.js';
|
||||
|
||||
let connected = false;
|
||||
ipc.config.appspace = IPC_CLIENT_APPSPACE;
|
||||
ipc.config.silent = true;
|
||||
|
||||
const oldConsoleLog = console.log;
|
||||
|
||||
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);
|
||||
|
||||
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() {
|
||||
this.emit('shutdown');
|
||||
process.exit(0);
|
||||
this.processLock.then(() => {
|
||||
process.exit(0);
|
||||
})
|
||||
}
|
||||
|
||||
restart() {
|
||||
this.emit('shutdown');
|
||||
if (connected) {
|
||||
ipc.of[name].emit(IPC_RESTART_EVENT);
|
||||
if (this.connected) {
|
||||
ipc.of[IPC_CLIENT_CONNECT_NAME].emit(IPC_RESTART_EVENT);
|
||||
}
|
||||
setTimeout(() => {
|
||||
process.exit(0);
|
||||
})
|
||||
}
|
||||
|
||||
get connected() {
|
||||
return connected;
|
||||
}
|
||||
}
|
||||
|
||||
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('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");
|
||||
});
|
||||
}
|
||||
124
src/Time.ts
124
src/Time.ts
|
|
@ -92,7 +92,7 @@ export default class Time extends Serializable {
|
|||
}
|
||||
|
||||
ctor() {
|
||||
this.targetTPS = 2000;
|
||||
this.targetTPS = 60;
|
||||
this.minute ??= 0;
|
||||
this.hour ??= 0;
|
||||
this.day ??= 0;
|
||||
|
|
@ -201,44 +201,112 @@ 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() {
|
||||
|
||||
this.advanceTime(1);
|
||||
const timeout = 1000 / this.targetTPS;
|
||||
// const start = ms4()
|
||||
const start = ms4();
|
||||
if(this.thing) {
|
||||
await this.thing.tick();
|
||||
}
|
||||
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`);
|
||||
// the higher the multitick, the more lopsided
|
||||
// ticks become in realtime, however, they rely
|
||||
// on fewer setTimeouts, which helps tick scheduling
|
||||
const multitick = 1;
|
||||
|
||||
if(wait < 0) {
|
||||
const ticksOver = (-wait / timeout) + 1;
|
||||
console.log(chalk.yellow('Can\'t keep up! Tick took ' + ticksOver.toFixed(2) + ' ticks (' + (timeout - wait).toFixed(4) + 'ms)'));
|
||||
}
|
||||
|
||||
|
||||
this.ticksInSecond ++;
|
||||
if(multitick > 1) {
|
||||
const timeout = (1000 / this.targetTPS) * multitick;
|
||||
const start = ms4();
|
||||
|
||||
if(end > this.lastTPSCheckpoint + 1000) {
|
||||
this.lastTPSCheckpoint = end;
|
||||
this.tps = this.ticksInSecond;
|
||||
this.ticksInSecond = 0;
|
||||
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 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)'));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
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)'));
|
||||
}
|
||||
|
||||
|
||||
this.ticksInSecond ++;
|
||||
|
||||
if(end > this.lastTPSCheckpoint + 1000) {
|
||||
this.lastTPSCheckpoint = end;
|
||||
this.tps = this.ticksInSecond;
|
||||
this.ticksInSecond = 0;
|
||||
}
|
||||
|
||||
if(this.paused) return;
|
||||
setTimeout(this._boundTick, normalizedWait);
|
||||
}
|
||||
|
||||
if(this.paused) return;
|
||||
setTimeout(this._boundTick, normalizedWait)
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
export interface Tickable {
|
||||
tick: () => Promise<void>
|
||||
tick: (seconds: number) => Promise<void>
|
||||
}
|
||||
|
||||
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.
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
Loading…
Reference in New Issue