Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ src/
contexts.ts # Solid contexts
types.ts # JSX IntrinsicElements
index.ts # Public API
tests/ # Unit (79) + Integration (13) + Component (9) = 101 tests
tests/ # 443 tests across 15 suites
docs/ # Design specification
examples/ # Runnable demos (breakout)
```
Expand Down
33 changes: 22 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,16 @@ solidion/
core/ # Renderer internals: meta, props, events, texture, scene-stack, frame, sync
hooks/ # L1a/L1b hooks: useTween, useSpring, useStateMachine, etc.
behaviors/ # L1c composition components: SpringBehavior, OscillateBehavior, etc.
components/ # Game, Scene, Preload, Overlay
components/ # Game, Scene, Preload, Overlay, GameLoop, Show, For
ecs/ # Data-driven ECS: pure step functions + System component
debug/ # Dev-only utilities: inspectBindings, profiling, expose
renderer.ts # solid-js/universal createRenderer implementation
contexts.ts # Solid contexts (Game, Scene, FrameManager, ParentNode)
types.ts # JSX IntrinsicElements type definitions
index.ts # Public API
tests/ # Unit tests (79) + integration tests (13) + component tests (9)
index.ts # Public API (L0–L1c)
tests/ # 443 tests across 15 suites
docs/ # Design specification
examples/ # Runnable demos
examples/ # Runnable demos (breakout, null-pow, floppy-heads, nadion-defense, aquarium)
```

## Testing
Expand All @@ -74,20 +76,25 @@ npm install
npm test
```

101 tests across 10 suites:
443 tests across 15 suites:

| Suite | Tests | Scope |
|---|---|---|
| renderer | 110 | Renderer logic (mock Phaser) |
| hooks | 107 | State machine, spring, tween, sequence, etc. |
| props | 48 | Property application & composition |
| ecs | 38 | Pure step functions & System component |
| texture | 29 | Texture auto-loading |
| components | 18 | Sync, reapplyProp, preload |
| visibility | 16 | Recursive visibility toggling |
| debug | 14 | Debug utilities & profiling |
| integration | 13 | Real Solid reactivity + renderer |
| contexts | 12 | Context providers & accessors |
| meta | 11 | Metadata & delta system |
| events | 9 | Event name resolution |
| props | 14 | Property application & composition |
| texture | 9 | Texture auto-loading |
| store-compat | 8 | SolidJS store compatibility |
| scene-stack | 5 | Scene stack management |
| frame | 5 | Frame callback lifecycle |
| renderer | 12 | Renderer logic (mock Phaser) |
| hooks | 14 | State machine & sequence logic |
| components | 9 | Sync, reapplyProp, preload |
| **integration** | **13** | **Real Solid reactivity + renderer** |

## Entry Points

Expand Down Expand Up @@ -124,6 +131,10 @@ See [docs/solidion-spec.md](docs/solidion-spec.md) for the full design specifica
See [examples/](examples/) for runnable demos.

- **[Breakout](examples/breakout/)** — Block breaker game demonstrating reactive signals, frame-loop physics, batch updates, and conditional state
- **[Null Pow!](examples/null-pow/)** — Pac-Man-style maze game with ghost AI, useOverlap collision, and useScene keyboard input
- **[Floppy Heads](examples/floppy-heads/)** — Flappy Bird-style game with procedural pipe generation and score tracking
- **[Nadion Defense](examples/nadion-defense/)** — Space Invaders-style tower defense with 40 reactive enemies and projectile pools
- **[Aquarium](examples/aquarium/)** — Hybrid ECS + hooks demo with fish, food, bubbles, jellyfish, and seaweed

## Why "Solidion"?

Expand Down

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion examples/aquarium/dist/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
}
.footer a { color: #4488cc; text-decoration: none; }
</style>
<script type="module" crossorigin src="./assets/index-DXpeFDb9.js"></script>
<script type="module" crossorigin src="./assets/index-CBWJ4zHt.js"></script>
</head>
<body>
<div id="game-container"></div>
Expand Down
1 change: 1 addition & 0 deletions examples/aquarium/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export default defineConfig({
"solidion/ecs": resolve(__dirname, "../../src/ecs/index.ts"),
"solidion/core": resolve(__dirname, "../../src/core/index.ts"),
"solidion/debug": resolve(__dirname, "../../src/debug/index.ts"),
"solidion/renderer": resolve(__dirname, "../../src/renderer.ts"),
"solidion": resolve(__dirname, "../../src/index.ts"),
"solid-js/store": resolve(rootModules, "solid-js/store/dist/store.js"),
"solid-js/universal": resolve(rootModules, "solid-js/universal/dist/universal.js"),
Expand Down

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion examples/breakout/dist/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
}
.footer a { color: #7fdbca; text-decoration: none; }
</style>
<script type="module" crossorigin src="./assets/index-C5iHtZ1c.js"></script>
<script type="module" crossorigin src="./assets/index-ClY0sCA3.js"></script>
</head>
<body>
<div id="game-container"></div>
Expand Down
1 change: 1 addition & 0 deletions examples/breakout/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export default defineConfig({
"solidion/ecs": resolve(__dirname, "../../src/ecs/index.ts"),
"solidion/core": resolve(__dirname, "../../src/core/index.ts"),
"solidion/debug": resolve(__dirname, "../../src/debug/index.ts"),
"solidion/renderer": resolve(__dirname, "../../src/renderer.ts"),
"solidion": resolve(__dirname, "../../src/index.ts"),
"solid-js/universal": resolve(rootModules, "solid-js/universal/dist/universal.js"),
"solid-js": resolve(rootModules, "solid-js/dist/solid.js"),
Expand Down

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion examples/floppy-heads/dist/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
}
.footer a { color: #7fdbca; text-decoration: none; }
</style>
<script type="module" crossorigin src="./assets/index-BQY7vmBW.js"></script>
<script type="module" crossorigin src="./assets/index-BTNBT8dr.js"></script>
</head>
<body>
<div id="game-container"></div>
Expand Down
1 change: 1 addition & 0 deletions examples/floppy-heads/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export default defineConfig({
"solidion/ecs": resolve(__dirname, "../../src/ecs/index.ts"),
"solidion/core": resolve(__dirname, "../../src/core/index.ts"),
"solidion/debug": resolve(__dirname, "../../src/debug/index.ts"),
"solidion/renderer": resolve(__dirname, "../../src/renderer.ts"),
"solidion": resolve(__dirname, "../../src/index.ts"),
// Deduplicate solid-js: ensure both example and library code use the
// same instance, AND use the browser build (not server/SSR).
Expand Down

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion examples/nadion-defense/dist/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
}
.footer a { color: #ff9944; text-decoration: none; }
</style>
<script type="module" crossorigin src="./assets/index-BtiCr2mZ.js"></script>
<script type="module" crossorigin src="./assets/index-DirEFGQ8.js"></script>
</head>
<body>
<div id="game-container"></div>
Expand Down
1 change: 1 addition & 0 deletions examples/nadion-defense/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export default defineConfig({
"solidion/ecs": resolve(__dirname, "../../src/ecs/index.ts"),
"solidion/core": resolve(__dirname, "../../src/core/index.ts"),
"solidion/debug": resolve(__dirname, "../../src/debug/index.ts"),
"solidion/renderer": resolve(__dirname, "../../src/renderer.ts"),
"solidion": resolve(__dirname, "../../src/index.ts"),
// Deduplicate solid-js: ensure both example and library code use the
// same instance, AND use the browser build (not server/SSR).
Expand Down

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion examples/null-pow/dist/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
}
.footer a { color: #00cc88; text-decoration: none; }
</style>
<script type="module" crossorigin src="./assets/index-157JVz5-.js"></script>
<script type="module" crossorigin src="./assets/index-yj2HKat-.js"></script>
</head>
<body>
<div id="game-container"></div>
Expand Down
1 change: 1 addition & 0 deletions examples/null-pow/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export default defineConfig({
"solidion/ecs": resolve(__dirname, "../../src/ecs/index.ts"),
"solidion/core": resolve(__dirname, "../../src/core/index.ts"),
"solidion/debug": resolve(__dirname, "../../src/debug/index.ts"),
"solidion/renderer": resolve(__dirname, "../../src/renderer.ts"),
"solidion": resolve(__dirname, "../../src/index.ts"),
// Deduplicate solid-js: ensure both example and library code use the
// same instance, AND use the browser build (not server/SSR).
Expand Down
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
},
"./debug": {
"import": "./src/debug/index.ts"
},
"./renderer": {
"import": "./src/renderer.ts"
}
},
"scripts": {
Expand Down
1 change: 1 addition & 0 deletions site/astro.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ export default defineConfig({
{ slug: "guides/components" },
{ slug: "guides/hooks" },
{ slug: "guides/behaviors" },
{ slug: "guides/ecs" },
],
},
{
Expand Down
4 changes: 4 additions & 0 deletions site/src/content/docs/guides/behaviors.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ description: Declarative behavior components for composition

Behaviors (L1c layer) provide declarative composition for common game patterns. They can be used as JSX children of game objects.

```tsx
import { SpringBehavior, OscillateBehavior, FollowBehavior, VelocityBehavior } from "solidion";
```

## SpringBehavior

Attach spring physics to a game object property.
Expand Down
4 changes: 4 additions & 0 deletions site/src/content/docs/guides/components.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ description: Built-in Solidion components

Solidion provides high-level components for managing Phaser's game lifecycle.

```tsx
import { Game, Scene, Preload, Overlay, GameLoop, Show, For, Index } from "solidion";
```

## Game

The root component that creates a Phaser game instance.
Expand Down
84 changes: 84 additions & 0 deletions site/src/content/docs/guides/ecs.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
---
title: ECS (Entity Component System)
description: Data-driven pattern for bulk entity processing
---

The ECS pattern (`solidion/ecs`) is for games with many entities of the same type — 10+ fish, 30+ bullets, etc. It combines SolidJS `createStore` with pure step functions and declarative `System` components.

```tsx
import { System, forActive, createSystemFactory } from "solidion/ecs";
import {
springStep, velocityStep, followStep,
oscillationStep, fsmStep, fsmSend,
tweenStep, tweenLerp,
} from "solidion/ecs";
```

## When to use ECS vs Hooks

| Pattern | When |
|---------|------|
| **Hooks** (`useSpring`, `useStateMachine`, ...) | Few entities (1–5), unique complex behavior per entity |
| **ECS** (`System` + step functions) | Many entities (10+), shared behavior definitions, single store |

## Pure Step Functions

Step functions are the same algorithms used inside `useSpring`, `useOscillation`, etc., extracted as pure functions for bulk processing. They take current state + config + delta time, and return the next state.

```tsx
import { springStep, type SpringState, type SpringConfig } from "solidion/ecs";

// Advance a spring by delta seconds
const next: SpringState = springStep(
{ x: 0, y: 0, vx: 0, vy: 0 },
{ targetX: 100, targetY: 200, stiffness: 120, damping: 14 },
1 / 60,
);
```

Available step functions:

| Function | Description |
|----------|-------------|
| `springStep` | Damped spring simulation |
| `oscillationStep` | Sine-wave oscillation |
| `velocityStep` | Velocity + acceleration + bounds/bounce |
| `followStep` | Exponential decay toward a target |
| `fsmStep` / `fsmSend` | Finite state machine transitions |
| `tweenStep` / `tweenLerp` | Tween interpolation |

## System Component

`System` registers a per-frame callback. Place it inside `<Game>` or `<Scene>` — JSX child order determines execution order.

```tsx
const [store, setStore] = createStore({ fish: [...] });

<Game>
<System
when={() => phase() === "play"}
update={(time, delta) => {
forActive(store.fish, (f, i) => {
const next = springStep(f, f.config, delta / 1000);
setStore("fish", i, next);
});
}}
/>
</Game>
```

## forActive

Helper to iterate only active entities in a store array:

```tsx
forActive(store.entities, (entity, index) => {
// Only called for entities where entity.active !== false
const next = velocityStep(entity, entity.config, delta / 1000);
setStore("entities", index, next);
});
```

## Full Example

See [examples/aquarium/](https://github.com/penta2himajin/solidion/tree/main/examples/aquarium) for a complete hybrid ECS + hooks demo with fish, food, bubbles, and more.
5 changes: 5 additions & 0 deletions site/src/content/docs/guides/hooks.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ description: Solidion hooks for animations, state machines, and more

Solidion provides hooks (L1a layer) that integrate Phaser features with SolidJS reactivity.

```tsx
import { useTween, useStateMachine, useSequence, useOverlap } from "solidion"; // L1a
import { useSpring, useFollow, useOscillation, useVelocity } from "solidion"; // L1b
```

## useTween

Animate properties with Phaser tweens, controlled reactively.
Expand Down
4 changes: 4 additions & 0 deletions site/src/content/docs/ja/guides/behaviors.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ description: コンポジション用の宣言的Behaviorコンポーネント

Behaviors(L1cレイヤー)は一般的なゲームパターンのための宣言的なコンポジションを提供します。ゲームオブジェクトのJSX子要素として使用できます。

```tsx
import { SpringBehavior, OscillateBehavior, FollowBehavior, VelocityBehavior } from "solidion";
```

## SpringBehavior

ゲームオブジェクトのプロパティにスプリング物理を付与します。
Expand Down
4 changes: 4 additions & 0 deletions site/src/content/docs/ja/guides/components.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ description: Solidionの組み込みコンポーネント

SolidionはPhaserのゲームライフサイクルを管理するための高レベルコンポーネントを提供します。

```tsx
import { Game, Scene, Preload, Overlay, GameLoop, Show, For, Index } from "solidion";
```

## Game

Phaserゲームインスタンスを作成するルートコンポーネントです。
Expand Down
Loading
Loading