franke-arcade-sdk.js hinzugefügt
This commit is contained in:
@@ -0,0 +1,149 @@
|
||||
// FrankieSDK v1 — include this in your arcade game to talk to Frankie OS.
|
||||
//
|
||||
// ============================================================================
|
||||
// GAME STRUCTURE
|
||||
// ============================================================================
|
||||
// Your game must be packaged as a .zip containing:
|
||||
//
|
||||
// my-game.zip
|
||||
// ├── frankie-game.json ← required manifest (see format below)
|
||||
// ├── index.html ← required entry point
|
||||
// └── assets/ ← optional: JS, CSS, images, audio, etc.
|
||||
//
|
||||
// ============================================================================
|
||||
// frankie-game.json FORMAT
|
||||
// ============================================================================
|
||||
// {
|
||||
// "id": "my-game", // slug: lowercase letters, digits, hyphens (1-64 chars)
|
||||
// "version": "1.0.0", // your game version
|
||||
// "title": "My Game", // shown on the cartridge
|
||||
// "tagline": "A one-line pitch", // shown under the title
|
||||
// "icon": "🎮", // emoji shown on the cartridge
|
||||
// "kind": "ARCADE", // badge: ARCADE | VS | LLM | PET
|
||||
// "author": "Your Name", // shown in the admin panel
|
||||
// "order": 50, // sort position in the arcade grid (lower = first)
|
||||
// "sdk_version": 1 // must be 1; future versions may be incompatible
|
||||
// }
|
||||
//
|
||||
// ============================================================================
|
||||
// LIFECYCLE HOOKS (events received FROM Frankie)
|
||||
// ============================================================================
|
||||
// sdk.on('init', ({ userId, username, gameId, theme }) => { ... })
|
||||
// Called once after the iframe loads. Initialize your game here.
|
||||
// You MUST call sdk.emit('ready') when your game has finished loading.
|
||||
//
|
||||
// sdk.on('pause', () => { ... })
|
||||
// Called when the arcade overlay loses focus (e.g. user switches tab).
|
||||
// Pause timers, animations, and any ongoing audio.
|
||||
//
|
||||
// sdk.on('resume', () => { ... })
|
||||
// Called when the overlay regains focus. Resume paused state.
|
||||
//
|
||||
// ============================================================================
|
||||
// EVENTS EMITTED TO Frankie
|
||||
// ============================================================================
|
||||
// sdk.emit('ready')
|
||||
// Tell Frankie your game is loaded and ready. Required after 'init'.
|
||||
//
|
||||
// sdk.emit('xp', { amount: number, reason: string })
|
||||
// Award XP to the player. 'reason' is a short label shown in toasts.
|
||||
//
|
||||
// sdk.emit('win')
|
||||
// Record a win for this game (increments win counter and awards XP).
|
||||
//
|
||||
// sdk.emit('score', { value: number })
|
||||
// Submit a high score. Frankie keeps the all-time best per game.
|
||||
//
|
||||
// sdk.emit('close')
|
||||
// Close the game and return to the arcade grid.
|
||||
//
|
||||
// ============================================================================
|
||||
// LLM ACCESS (for kind: "LLM" games)
|
||||
// ============================================================================
|
||||
// const reply = await sdk.llm([
|
||||
// { role: 'system', content: 'You are a trivia host.' },
|
||||
// { role: 'user', content: 'Ask me a question.' }
|
||||
// ])
|
||||
// console.log(reply) // string — the model's response text
|
||||
//
|
||||
// ============================================================================
|
||||
// EXAMPLE (vanilla JS)
|
||||
// ============================================================================
|
||||
// import sdk from './frankie-sdk.js'
|
||||
//
|
||||
// sdk.on('init', ({ username }) => {
|
||||
// document.querySelector('#welcome').textContent = `Hello, ${username}!`
|
||||
// sdk.emit('ready')
|
||||
// })
|
||||
//
|
||||
// sdk.on('pause', () => clearInterval(gameLoop))
|
||||
// sdk.on('resume', () => { gameLoop = setInterval(tick, 16) })
|
||||
//
|
||||
// function onPlayerWin() {
|
||||
// sdk.emit('win')
|
||||
// sdk.emit('xp', { amount: 50, reason: 'Victory' })
|
||||
// sdk.emit('score', { value: playerScore })
|
||||
// }
|
||||
// ============================================================================
|
||||
|
||||
const FrankieSDK = (() => {
|
||||
const _handlers = {}
|
||||
const _llmResolvers = {}
|
||||
|
||||
// _handle dispatches an inbound postMessage event to the registered hook.
|
||||
function _handle(type, payload) {
|
||||
const hook = _handlers[type]
|
||||
if (typeof hook === 'function') hook(payload)
|
||||
}
|
||||
|
||||
// Boot: listen for messages from the Frankie parent frame.
|
||||
window.addEventListener('message', (event) => {
|
||||
const { type, payload, id } = event.data || {}
|
||||
if (typeof type !== 'string' || !type.startsWith('FRANKIE_')) return
|
||||
|
||||
const hook = type.slice(8).toLowerCase() // FRANKIE_INIT → 'init'
|
||||
|
||||
// LLM responses are resolved as promises rather than dispatched as hooks.
|
||||
if (hook === 'llm_response') {
|
||||
const resolve = _llmResolvers[id]
|
||||
if (typeof resolve === 'function') {
|
||||
resolve(payload?.content ?? '')
|
||||
delete _llmResolvers[id]
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
_handle(hook, payload)
|
||||
})
|
||||
|
||||
return {
|
||||
// on registers a lifecycle hook. Returns the SDK for chaining.
|
||||
on(event, handler) {
|
||||
_handlers[event] = handler
|
||||
return this
|
||||
},
|
||||
|
||||
// emit sends a typed event to the Frankie parent frame.
|
||||
emit(event, payload = {}) {
|
||||
window.parent.postMessage(
|
||||
{ type: `FRANKIE_${event.toUpperCase()}`, payload },
|
||||
'*'
|
||||
)
|
||||
},
|
||||
|
||||
// llm sends a chat-completion request to Frankie's LLM and returns a Promise
|
||||
// that resolves with the model's reply as a string.
|
||||
llm(messages) {
|
||||
return new Promise((resolve) => {
|
||||
const id = `llm_${Date.now()}_${Math.random().toString(36).slice(2)}`
|
||||
_llmResolvers[id] = resolve
|
||||
window.parent.postMessage(
|
||||
{ type: 'FRANKIE_LLM_REQUEST', id, payload: { messages } },
|
||||
'*'
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
})()
|
||||
|
||||
export default FrankieSDK
|
||||
Reference in New Issue
Block a user