This commit is contained in:
Andras Schmelczer 2026-08-22 20:59:46 +01:00
commit 98c4d63756
5 changed files with 155 additions and 223 deletions

View file

@ -1,23 +1,7 @@
let _seed = Math.random();
let seed = Math.random();
export function setRandomSeed(value: number) {
_seed = value;
}
export function chooseRandom<T>(values: Array<T>): T | undefined {
const to = values.length;
if (to === 0) {
return undefined;
}
return values[Math.floor(getRandomInRange(0, to))];
}
export function getRandomInRange(from: number, to: number): number {
return from + getRandom() * (to - from);
}
export function getRandom(): number {
let t = (_seed += 0x6d2b79f5);
function getRandom(): number {
let t = (seed += 0x6d2b79f5);
t = Math.imul(t ^ (t >>> 15), t | 1);
t ^= t + Math.imul(t ^ (t >>> 7), t | 61);
return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
@ -25,12 +9,18 @@ export function getRandom(): number {
export const Random = {
get seed() {
return _seed;
return seed;
},
set seed(v: number) {
_seed = v;
set seed(value: number) {
seed = value;
},
choose: chooseRandom,
getRandomInRange,
getRandom,
getRandomInRange(from: number, to: number): number {
return from + getRandom() * (to - from);
},
choose<T>(values: Array<T>): T | undefined {
return values.length === 0
? undefined
: values[Math.floor(getRandom() * values.length)];
},
};

View file

@ -34,8 +34,8 @@ export class PlanetBase extends GameObject {
this.vertices.length;
}
// Single rule for the dead-band: scoring (server) and every tint (client)
// read this rather than duplicating the comparison.
// The one capture rule: server flips and scoring, client tints and the
// keystone arrow all read this.
public get team(): CharacterTeam {
return Math.abs(this.ownership - 0.5) < settings.planetControlThreshold
? CharacterTeam.neutral

View file

@ -78,7 +78,9 @@ export const marchCircle = (
);
}
vec2.scaleAndAdd(body.center, body.center, direction, deltaLength);
// lastFreeDistance, not deltaLength: on a completed march they are equal, and
// if the step budget ran out it is the furthest point actually checked.
vec2.scaleAndAdd(body.center, body.center, direction, lastFreeDistance);
return {
hitSurface: false,

View file

@ -30,12 +30,9 @@ export const settings = {
maxGravityDistance: 800,
minGravityDistance: 1,
maxGravityQ: 5000,
// Neutral dead-band around 50% ownership; the rendered ring uses the same
// threshold as scoring so visuals match state.
// Neutral dead-band around 50% ownership. The single capture rule: flips,
// scoring and every client-side tint all read PlanetBase.team.
planetControlThreshold: 0.12,
// Schmitt trigger: extra margin beyond planetControlThreshold before a flip
// pays out again, so boundary-hovering doesn't re-trigger the reward.
planetFlipHysteresis: 0.06,
playerMaxHealth: 100,
maxGravityStrength: 50000,
planetMinReferenceRadius: 150,
@ -171,11 +168,6 @@ export const settings = {
chargeShotRecoilMax: 650,
// Capped so a forged timestamp cannot spawn a shot arbitrarily far downrange.
maxProjectileCatchUpSeconds: 0.2,
reconnectGraceSeconds: 30,
// DoS guard: parsing is synchronous with the physics loop, so one oversized
// message stalls the tick for everyone.
maxInboundMessageBytes: 16 * 1024,

View file

@ -7,6 +7,7 @@
"target": "es6",
"esModuleInterop": true,
"strict": true,
"experimentalDecorators": true,
"moduleResolution": "node",
"ignoreDeprecations": "6.0",
"module": "commonjs",