Bootstrapping pixel-art engine...

OLDVIBE

Engine 2D pixel-art & games mobile-first · sprite builder programático + Phaser carregado da CDN Iandara em runtime.

Character 4 frames · 16×24

Walking animation com legs alternados e braços opostos. Palette-swappable: altere as cores e redesenhe a forma.

sprite(16, 24) · 4 frames
House 2 frames · 32×28

Casa pixel com variação dia/noite. Demonstra .fill(), ramp() e layer frame-dependente via .v(key).

sprite(32, 28) · frame: 0 (dia)
Tree 3 frames · 12×20

Árvore com balanço ao vento em 3 frames. Usa .layer(s => ...) para a copa se mover em relação ao tronco fixo.

sprite(12, 20) · 3 frames
API — sprite(w, h) data-first · testável

Builder declarativo: .palette(), .rect(), .frames(n, fn), .layer(fn). to_ops(frame) é puro (sem browser) — testável via node --test. to_canvas(frame) rasteriza.

const hero = oldvibe.sprite(16, 24)   .palette({skin:'#f5c5a0', coat:'#2d6ba1'})   .rect(4, 0, 8, 8, 'skin') // cabeça   .rect(3, 8, 10, 10, 'coat') // torso   .frames(4, f => ({leg: [0,2,0,-2][f]}))   .layer(s => s.rect(3, 18+s.v('leg'), 4, 5, 'boot'))
hero.to_ops(2) // → [{x,y,w,h,color}, …] (puro) hero.to_canvas(0) // → <canvas> (browser)
Sky Texture sky_texture(opts)

Gradiente de céu com estrelas, lua e silhueta de montanhas procedurais. Cada seed gera uma paisagem determinística diferente. Cores top/mid/bottom configuram o tema.

Forest Texture forest_texture(opts)

Fileiras de árvores pixel para parallax de fundo. shade controla o tom (0 = mais claro/frente, 1 = mais escuro/fundo).

Mountain Points mountain_points(n, opts)

Silhueta procedural como array de pontos [[x, y], …] normalizados (0..1). Puro — sem DOM, testável com node --test. Seed garante determinismo.

Palette Ramp ramp(hex) · PALETTES

ramp(cor) gera 4 tons: dark / main / light / highlight. PALETTES.retro traz um conjunto pré-construído. Use em sprites para sombra e destaque automáticos.

ramp( )
River Crossing solve(spec) · BFS

Leve lobo 🐺, ovelha 🐑 e repolho 🥦 para a margem direita. O barco carrega o fazendeiro e no máximo 1 item. Lobo + ovelha sem fazendeiro = problema. Ovelha + repolho sem fazendeiro = problema. Use Dica para o BFS sugerir o próximo movimento.

Margem Esquerda
barco
◀ ESQ
Margem Direita
Selecione um item da margem esquerda para embarcar, depois atravesse.
Telemetria solve() + rate()

Solução ótima tem 7 travessias. rate(moves, 7) retorna estrelas baseado na eficiência.

movimentos 0
dicas 0
status jogando
rating
--:--:-- SYSTEM puzzle inicializado
API Solver solve · rate · BFS genérico

O BFS é agnóstico ao domínio. actions(state) retorna as ações válidas do estado atual. apply(state, action) deve ser não-mutante.

const next_action = oldvibe.solve({   start: current_state,   goal: s => s.right.size === 3 && s.farmer === 'right',   actions: state => get_valid_moves(state),   apply: (s, a) => transition(s, a),   key: s => `${s.farmer}|${[...s.right].sort()}` })
const r = oldvibe.rate(moves, 7, {   thresholds: [0, 2, 5],   labels: ['Perfeito!', 'Bom!', 'Funciona', 'Pode melhorar'] }) // → {stars: 0-3, label: string}
Mini Game create_game · responsive · Phaser lazy CDN

O Phaser 3.80.1 é carregado lazy da CDN Iandara via ensure_phaser(). O pacote também expõe viewport_dims(), layout_metrics(), game_hud_layout(), create_choice_sheet() e create_paged_panel() para jogos mobile-first sem overlap.

Pronto para lançar

Phaser carrega da CDN Iandara no primeiro clique.
Desktop: ← →  |  Mobile: D-pad touch.

Aguardando lançamento. Phaser não carregado.
Lazy Load Pattern ensure_phaser()

Phaser é UMD clássico (seta window.Phaser). O loader injeta um <script> sem type=module e resolve o global. Promise é cacheada — segunda chamada é instantânea.

// UMD não inclui Phaser (18.7 KB) <script src="cdn.iandara.com/.../oldvibe.umd.min">
// ensure_phaser() → promise cacheada: await oldvibe.ensure_phaser() // window.Phaser agora existe
// create_game aguarda automaticamente: const g = await oldvibe.create_game({   parent: 'container-id',   responsive: {base:390, min_aspect:1.45, max_aspect:2.25},   scenes: Phaser => [     oldvibe.make_boot(Phaser, {next:'Title', generate}),     oldvibe.make_title(Phaser, {next:'Game', build}),     oldvibe.make_game(Phaser, {create, tick})   ] })
const ui = oldvibe.layout_metrics({width:g.config.width, height:g.config.height})
const hud = oldvibe.game_hud_layout(ui)
oldvibe.create_choice_sheet(scene, {title:'CASA', items, on_select})
Estrutura do Package flat modules · 18.7 KB UMD

Sem src/ — módulos no root do package, orquestrados pelo main.mjs e empacotados pelo build.mjs.

packages/oldvibe/
├── main.mjsentry + namespace
├── build.mjsIIFE → UMD
├── cdn.mjsURLs CDN Iandara
├── phaser-loader.mjsensure_phaser lazy
├── pixel.mjsSprite builder
├── palette.mjsramp · darken · mix
├── textures.mjsregister · add_anim
├── game.mjscreate_game async
├── ui.mjsHUD · buttons · sheets
├── scenes.mjsmake_boot/title/game
├── controls.mjsD-pad · touch · keys
├── dialog.mjsTypewriter · Dialog
├── parallax.mjssky · forest · mtn
├── crt.mjsscanlines · vignette
├── solver.mjsBFS genérico
└── rating.mjsrate · estrelas