playable-game-object-manager
v1.0.0
Published
Safe AST parser and React Hooks for dynamically extracting and updating Javascript Game Objects in HTML strings.
Downloads
125
Maintainers
Readme
playable-game-object-manager
A powerful, entirely safe AST-based parser and React Hook library specifically designed for dynamically extracting, reading, and mutating Javascript game_object configurations natively embedded inside HTML template strings.
Because it utilizes an Abstract Syntax Tree (AST), it does not rely on new Function() or eval() rendering it secure for use in browser applications (e.g. template editors, CMS live previews).
Installation
npm install playable-game-object-managerHow to Publish to NPM
If you are developing this library and want to publish your latest changes:
- Ensure your code is compiled into the
dist/directory by running:npm run build - Log into your NPM account via the terminal (if you haven't already):
npm login - Publish it publically!
npm publish --access public
How It Works
Instead of relying on fragile and chaotic Regular Expressions to hunt down and parse javascript objects embedded in the HTML file, this library features a Custom Tokenizer and AST Parser.
- Extraction: It locates the
window.game_object = {assignment in the HTML string bounds. - Tokenization: It slices out the Javascript text and breaks it into semantic tags (Tokens).
- AST Parsing: It builds a structural tree out of these tokens (AST Node Tree).
- Evaluation: It recurses through this tree and spits out a 100% native Javascript Object, entirely bypassing
eval(). - Bridge Script injection: The hook automatically concatenates a hidden "Bridge Script" directly into the HTML's
<body>. This bridge script listens for'game_object_updated'events allowing the innergame_objectto accept updates instantly!
The React Hook: useGameObjectManager
This single hook is the core of the library! It takes your HTML string or a URL and fully automates the parsing pipeline.
Hook Options
url(string): If provided, the hook will asynchronously download the HTML code from the URL and parse it.initialHtml(string): If you already have the HTML loaded locally in memory, pass it here natively.
Hook Returns (State variables)
rawHtml: The exact strict, unmodified HTML string.previewHtml: The HTML string with the Bridge Script secretly injected into it. You should always pass this to your iframe!gameObject: Your completely parsed Javascript Object. You can read it, list its themes, or inspect its logic!isLoading: Returnstruewhile theurlis downloading.error: Returns an error if the URL failed to fetch.
Hook Functions
updateObject(newObj): Pass an updated Javascript object directly into this callback function. It will automatically serialize the object, locate the bounds within the structural HTML string, and rebuild the template with your new object embedded directly within the code.setRawHtml(string): Use this if you need to load an entirely new template wrapper manually!
Usage Example: Live Iframe Editing
We provide two approaches for updating your template depending on whether you want to strictly save/re-render the HTML or seamlessly update a running iframe without flicker.
Approach 1: Hard Save & Reload (updateObject)
Calling updateObject() literally modifies the underlying HTML string, causing the iframe to completely reload with the new codebase securely embedded inside.
import React from 'react';
import { useGameObjectManager } from 'playable-game-object-manager';
export default function GameEditor() {
const { previewHtml, gameObject, updateObject, isLoading } = useGameObjectManager({
url: "https://your-server.com/example_template.html"
});
if (isLoading) return <div>Loading...</div>;
const handleHardUpdate = () => {
// This alters the underlying HTML text and forces a full iframe reload
updateObject({ ...gameObject, newProp: 'Hard Save' });
};
return (
<div>
<button onClick={handleHardUpdate}>Save to Template</button>
<iframe srcDoc={previewHtml} width="100%" height="600" />
</div>
);
}Approach 2: Seamless Hot-Reload (usePlayableLivePreview)
For fine-tuning controls like Color Pickers or Sliders, you don't want the iframe to wipe & reload on every frame of a drag. Instead, attach the companion hook usePlayableLivePreview to directly beam the new data into the already-running bridge script!
import React, { useRef } from 'react';
import { useGameObjectManager, usePlayableLivePreview } from 'playable-game-object-manager';
export default function SeamlessGameEditor() {
const iframeRef = useRef(null);
// 1. Get the parsed object and template HTML
const { previewHtml, gameObject, isLoading } = useGameObjectManager({
url: "https://your-server.com/example_template.html"
});
// 2. Initialize the hot-reload bridge Hook!
const { sendLiveUpdate } = usePlayableLivePreview(iframeRef);
if (isLoading) return <div>Loading...</div>;
const handleSmoothDrag = (newDuration) => {
const updated = { ...gameObject };
if (updated.GameProperties) {
updated.GameProperties.GameDuration = newDuration;
}
// This dynamically triggers the game update WITHOUT reloading the iframe!
sendLiveUpdate(updated);
};
return (
<div>
<button onClick={() => handleSmoothDrag(999)}>Cheat: Max Duration</button>
{/* 3. Attach your ref to the iframe */}
<iframe ref={iframeRef} srcDoc={previewHtml} width="100%" height="600" />
</div>
);
}