Add ur prototype idea

This commit is contained in:
John Alanbrook 2023-09-08 06:26:48 +00:00
parent a4111b01a5
commit cc879746e3
4 changed files with 110 additions and 14 deletions

View file

@ -37,6 +37,35 @@ A prefab can be opened up to edit on its own, without breaking the currently pla
In edit mode, there are no running scripts; only editing them.
## Components, objects, and levels
There are three distinct hierarchies of object-existence.
### Components
The most "bare metal" are the components. These are essentially hooks into the engine that tell it how to do particular things. For example, to render a sprite, Javascript does no rendering, but rather tells the engine to create an image and render it in a particular spot.
Components are rendered in an "ECS" style. To work, components must be installed on an entity.
### Entity
Entities are holders of components. Anything that needs a component will be an entity. Components rely on entites to render correctly. For example, the engine knows where to draw a sprite wherever its associated entity is.
### Levels
Levels are nothing more than groups of entities However, levels can also have a script on them. This level of scripting is the least efficient.
Levels do not have an associated gameobject inside the engine, and so are what you want if you just want to run some code.
## Prototyping model
All objects follow the prototyping model of inheritence. This makes it trivial to change huge swathes of the game, or make tiny adjustments to single objects, in a natural and intuitive way.
Components cannot be prototyped. They are tied directly to the entity they are bound to.
Entities can be prototyped out. What this means is that, when you select an object in the game, you can either make a "subtype" of it, where changes to the object trickle down to the created one, or a "sidetype" of it, which is a total duplicate of the object.
### Ur-types
An Ur-type is a thing which cannot be seen but which can stamp out copies of itself. Objects can be promoted to an ur-type, so if it is deleted, another one can later be made.
Levels can be subtyped, sidetyped, and urtyped, just like entities.
## Level model
The game world is made up of objects. Levels are collections of
objects. The topmost level is called "World". Objects are spawned into

View file

@ -51,7 +51,7 @@ void mYughLog(int category, int priority, int line, const char *file, const char
snprintf(buffer, ERROR_BUFFER, "%s:%d: %s, %s: %s\n", file, line, logstr[priority], catstr[category], msgbuffer);
log_print(buffer);
if (category != LOG_SCRIPT && priority >= 2)
if (category == LOG_SCRIPT && priority >= 2)
js_stacktrace();
}
#endif

View file

@ -198,6 +198,34 @@ Object.defineProperty(String.prototype, 'shift', {
});
Object.defineProperty(String.prototype, 'ext', {
value: function() {
return this.slice(this.lastIndexOf('.'));
}
});
Object.defineProperty(String.prototype, 'name', {
value: function() {
var s = this.lastIndexOf('/');
var e = this.lastIndexOf('.');
return this.slice(s+1,e);
}
});
Object.defineProperty(String.prototype, 'base', {
value: function() {
return this.slice(this.lastIndexOf('/')+1);
}
});
Object.defineProperty(String.prototype, 'dir', {
value: function() {
var e = this.lastIndexOf('/');
return this.slice(0, e);
}
});
/* ARRAY DEFS */
Object.defineProperty(Array.prototype, 'copy', {

View file

@ -16,8 +16,6 @@ function initialize()
if (IO.exists("config.js"))
load("config.js");
// prototypes.load_all();
if (Cmdline.play)
run("scripts/play.js");
else
@ -243,6 +241,7 @@ var Keys = {
load("scripts/physics.js");
load("scripts/input.js");
load("scripts/sound.js");
function screen2world(screenpos) { return Game.camera.view2world(screenpos); }
function world2screen(worldpos) { return Game.camera.world2view(worldpos); }
@ -1122,19 +1121,9 @@ Game.view_camera(World.spawn(camera2d));
win_make(Game.title, Game.resolution[0], Game.resolution[1]);
/* Default objects */
gameobject.clone("polygon2d", {
polygon2d: polygon2d.clone(),
});
gameobject.clone("edge2d", {
edge2d: bucket.clone(),
});
gameobject.clone("sprite", {
sprite: sprite.clone(),
});
var prototypes = {};
prototypes.ur = {};
prototypes.load_all = function()
{
if (IO.exists("proto.json"))
@ -1170,7 +1159,57 @@ prototypes.from_file = function(file)
var newobj = gameobject.clone(file, {});
var script = IO.slurp(file);
compile_env(`var self = this;${script}`, newobj, file);
prototypes.ur[file.name()] = newobj;
return newobj;
}
prototypes.from_file.doc = "Create a new ur-type from a given script file.";
prototypes.from_obj = function(name, obj)
{
var newobj = gameobject.clone(name, obj);
prototypes.ur[name] = newobj;
return newobj;
}
prototypes.load_config = function(name)
{
if (!prototypes.config) {
prototypes.config = {};
if (IO.exists("proto.json"))
prototypes.config = JSON.parse(IO.slurp("proto.json"));
}
Log.warn(`Loading a config for ${name}`);
if (!prototypes.ur[name])
prototypes.ur[name] = gameobject.clone(name);
return prototypes.ur[name];
}
prototypes.get_ur = function(name)
{
if (!prototypes.ur[name]) {
if (IO.exists(name + ".js"))
prototypes.from_file(name + ".js");
prototypes.load_config(name);
return prototypes.ur[name];
} else
return prototypes.ur[name];
}
var Gamestate = {};
prototypes.from_obj("polygon2d", {
polygon2d: polygon2d.clone(),
});
prototypes.from_obj("edge2d", {
edge2d: bucket.clone(),
});
prototypes.from_obj("sprite", {
sprite: sprite.clone(),
});