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
*.log
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",
"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"
}
}
}

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';
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;

View File

@ -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());
}

View File

@ -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() {

View File

@ -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");
});
}

View File

@ -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.

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