- GlitchHunter - 18/2/2025
... Click to Reveal
- GlitchHunter - 18/2/2025
... Click to Reveal
...its time i say this
ive kinda been working on this for a while in the background,
posting small snippets of codes,
the async engine was just the beginning,
i needed something to deal with time and interruptions,
but now we have that done,
and with eval handling interruptions,
there is nothing stopping this project from being made,
so behold...
well its time, im back at it again, this time, we have got the following features
- General Ideas
- redefining the api as a structured object, so it follows the rules below (1)
- if A contains B ingame, class A contains class B in code
World = new class { Code = new class { ... } Block = new class { ... } Entity = new class { ... } } //Structured api
- if world updates, so does class (eg onPlayerJoin, create extra player)
onPlayerJoin(id){ World.Entitys[id]= new World.Entity.Player } //Create new
- extend the api to utilise all possible infomation on the world
api.getMesh //more info getting than original api, each setter should have a getter and vice versa
- removing raw code in callbacks in favor of reactive coding, which handles all the callbacks for you (2)
- reactive coding,
react(()=>{}) //idk but idea
- attaching callbacks on the fly
Callback.Attach("onPlayerJoin",()=>{console.log("added")}) //adds new callback, making it dynamic addition and removal
- callback interception to TS
function onPlayerJoin(...args){TS.add(World.Code.Callback.onPlayerJoin, ...arg)} //how world code will most likely look like
- auto handling scope and removal (eg onPlayerLeave, remove listeners associated with player) (3)
removeListener.relysOn(playerId) //removes all from a certain player
- if extra global variables are added, they will be auto removed outside scope (simple globalThis check + deleted/move to local) if wanted
disposable(()=>{ a = 1,b = 2,c = 3 })
- will replicate
usingin bloxd for auto remove semantics
using variable = value //doesnt exist in bloxd let variable = using(value) //is poly fill for it
- will update event listeners if associated players or items no longer exist
addFragileListener() //will delete it self if something it relys on doesnt exist //(can mostly match if a specific error is thrown)
- making async engine a part of this (since timings will be allowed here, as well as waiting ect)
Async == Generator
TS.add(function*(){ console.log("hello from ...") yield; console.log("... Async Engine") }())
- redefining the api as a structured object, so it follows the rules below (1)
- what ill do better than bloxd
- Code Writing (4)
- handling code
if(!started && ready && !cooldown && !dead && ... )resolved into a state check
- looping behaviour
- no long running whiles, use Async.While()
while(inShop){...} //Bad, interrupted Async.While(inShop,()=>{ ... }) //good, runs forever till stop
- for loops will be managed by yield*
for(...){yield;...} //allows long running while loops
- for of will be handled via generators (data stream if needed)
for(prop of LARGE){yield; ... } //effective infinite data stream //LARGE is a generator in [Symbol.iterator](), so each time it spits out the next value
- management
- memory, infinite memory storage using chests
bim //infinite memory (not player specific)
- temporal, using threads
ThreadManager.add() //infinite time usage, threads
- interrupt units, idk, got any ideas lmao
eval() //Interrupt or give 5k IU
- handling code
- Code Execution (5)
- better execution
- handles cleanup of UI, timeouts, variables, has an auto dispose used, which when needed with automatically remove it if needed
let unused = new WeakVar() //if not referenced anymore, it will be garbage collected
- async engine will assist in this, time will be the 4th dimension of programming, allowing full control over time
Debug.set(true) //default branch is [] which is root //inside //root = {}, its id = 0, pointer = last edited or added branch, can be changed //if no argument is given when need id, assume pointer location Time.step() //step once Time.step(e=>e+1) //take yield output, change via function, then input back in code let id_1 = new Time.Branch([0]) //root = {1:{}}, id = 1 let id_2 = new Time.Branch(id) //root = {1:{2:{}}}, id = 2 //returns a getter so when Tree is access its consistent to the reference let id_3 = new Time.Branch(id) //root = {1:{2:{}},3:{}}, id = 3 //a node contains all of its successors inside it TimeTree.mainMerge(id_1,[1d_3]) //root = {1:[{2:{}},{3:{}}]}, id = 1 //main merge takes first argument and makes all following arguments merge with it
- Inspection
- will come packed with useful error messages and will use stack to show what happens
BetterErr => Error .name . message .stack ... //Extras will be added
- will allow to inspect enviroment in real time (log scope, log variables inside, log stack)
Debugger.inspect => Internal.Inspect => .stack .scope .snapshot ... //Extras will be added
- will come with a multitude of debugging help when activated, (thread watcher, listener logging, time logging, event activation ...)
Debugger.snapshot => .start .end .log //built in snapshot which inspects everything and keeps track of it
- better execution
- Code Launching (6)
- compiling
- when given the go ahead, the code will auto compile and then run on startup with each part running, making for easy launching of worlds
- will be compressed as much as possible
- can store as much as possible, will use eval to take your code
GE.Exe.Compile(`code`) //maybe either that or it runs the code and //then snapshots all current timeout and environment workings to them resume later, //will be compressed as much as possible //will use eval to gather and merge and execute your code
- execution
- coders will have full control over code if needed
- coders can pause and continue execution
- can activate a lockdown and if code is broken and could be exploited it will prevent anything else from running, until kill switch is deactivated
GE.Exe => .pause .continue .kill //allows to pause continue and even deactivate code across everywhere if needed //(powered by rate limiter and memory hell) //and pretty much nukes itself until every code is broken due to global this being gone //but does this in a controlled manner
- compiling
- Code Writing (4)
- Editing
- Click and Create
- will allow modules to be easily added
- allows you to use sticks to edit attributes directly rather than code
//All this is going to be abstracted to UI and Menus //to edit game at surface level without having to use coding, //use this if you arent comfortable with coding, //but for people who are comfortable with coding, this API is yours
- Connect to BACK-END
- the front end ease is for players who dont want to code that much, however if players do want to code directly, well ill expose the engines inner workings and the api i will provide it for your usage
- git like editing and backend variables resolving
- it will be based on git commands to commit to a branch but the main idea is pretty much code editing time travel, (add creates a new seed, add creates a new space branch, commit creates or builds on a time branch, reset --hard prunes the time tree, reset soft, moves the temporal edit point to a previous point ...), with the following models (time tree & pointer, space tree & pointer, temp & perm, multiple instances, (really just many branches of time tree))
- Click and Create
//global scoped fix, using polyfill idea
let forceLocal=(fn)=>{
let before = Reflect.ownKeys(globalThis) //snapshot keys before
fn() //run function
let after = Reflect.ownKeys(globalThis) //snapshot keys after
let globals = after.filter(e=>!before.includes(e)) //is in after but not before -> was added by fn
globals.map(e=>{delete globalThis[e]}) //delete those added
}
let fn = () => {
let scoped = 0 //is scoped
whoops = 0 //is not scoped, forceLocal will handle it
}
forceLocal(fn)
console.log(whoops) //throws error, forceLocal cleaned it up//scope inspector, useful for custom variable scoping
function inspectScope() {
try {
throw new Error(); //throws new error to extract stack generated
} catch (e) {
return e.stack //parses stack, details on how below
.trim() //removed unnecessary "\n" so next step can split each stack element one by one
.split("\n") //does the split
.slice(1) //removes itself "inspectScope" from stack
.map(line =>
line
.trim() //trims unnecessary spaces either side, due to indentation or otherwisw
.replace(/^at\s+/, "") //removed repeated element "at ", so pure stack snippet is left
.replace(/\s+/g, " ") //normalised spaces to always 1 space for next step
.split(" ") //splits the spaces to get more detail on snippet "ErrorPlace (<input>:LineNumber)"
)
}
}
function test() {
let b = 2;
const c = 3;
console.log(inspectScope())
}
test()//Scope Extractor, extracts references to each function
let Scope = {
calls:[],
getCallStack:function(){
this.calls = []
let step = arguments.callee
while(step){
this.calls.push(step)
step = step.caller
}
}
}
function Fn1(){
Scope.getCallStack()
}
function Fn2() {
Fn1();
}
function Fn3() {
Fn2();
}
Fn3(1,2,3);
console.log(Scope.calls)
/*
[
[Function: getCallStack],
[Function: Fn1],
[Function: Fn2],
[Function: Fn3],
[Function (anonymous)]
]
*///Observe GlobalThis through a proxy
;(()=>{
let {Reflect, Object, Proxy, Date} = globalThis
let active = false
let snapshot = function (obj) {
return Reflect.ownKeys(obj).reduce(function(o, k) {
try { o[k] = obj[k] } catch(e) {}
return o
}, {})
}
let trap = Object.fromEntries(
["set","get"].map(op => [op, (...args) => {
active = false
try{
console.log(args[1])
return Reflect[op](...args)
}finally{
active = true
}
}])
)
let HANDLE = new Proxy({}, {
get(_, t) {
return (active ? trap[t] : void 0)
}
});
Reflect.setPrototypeOf(globalThis, new Proxy(snapshot(globalThis), HANDLE))
Reflect.ownKeys(globalThis).filter(k=>k !== "globalThis").forEach(k => {
try { Reflect.deleteProperty(globalThis, k) } catch(e) {}
});
active = true
})();