reorganize
This commit is contained in:
375
CLAUDE.md
375
CLAUDE.md
@@ -1,375 +0,0 @@
|
||||
# CLAUDE.md
|
||||
|
||||
## Build Commands
|
||||
Run 'make' to make cell.
|
||||
|
||||
### Testing
|
||||
After install with 'make', just run 'cell' and point it at the actor you want to launch. "cell tests/toml" runs the actor "tests/toml.js"
|
||||
|
||||
## Scripting language
|
||||
This is called "cell", a variant of JavaScript with important differences. See docs/cell.md for detailed language documentation.
|
||||
|
||||
## Architecture Overview
|
||||
|
||||
Prosperon is an actor-based game engine.
|
||||
|
||||
### Actor Model
|
||||
- Each actor runs on its own thread
|
||||
- Communication only through message passing (no shared JavaScript objects)
|
||||
- Hierarchical actor system with spawning/killing
|
||||
- Actor lifecycle: awake, update, draw, garbage collection
|
||||
|
||||
### Cell Language Style Guide
|
||||
- Use `use()` function for imports (Misty-style, not ES6 import/export)
|
||||
- Prefer closures and javascript objects and prototypes over ES6 style classes
|
||||
- Follow existing JavaScript patterns in the codebase
|
||||
- Functions as first-class citizens
|
||||
- Use `def` for constants (not const)
|
||||
- Use `var` for variables (block-scoped like let)
|
||||
- Check for null with `== null` (no undefined in Cell)
|
||||
- Use `==` for equality (always strict, no `===`)
|
||||
- See docs/cell.md for complete language reference
|
||||
|
||||
### Core Systems
|
||||
1. **Actor System** (scripts/core/engine.js)
|
||||
- Message passing via `send()`, `$_.receive()`
|
||||
- Actor spawning/management
|
||||
- Register-based component system (update, draw, gui, etc.)
|
||||
|
||||
2. **Module System**
|
||||
- `use()` function for loading modules
|
||||
- Module paths: `scripts/modules/`, `scripts/modules/ext/`
|
||||
- Custom QuickJS build with embedded C modules
|
||||
|
||||
3. **Build System**
|
||||
- Meson build configuration (Makefile is convenience wrapper)
|
||||
- Multiple platform targets (Windows, macOS, Linux, Web)
|
||||
- Custom QuickJS build in `subprojects/`
|
||||
- Uses SDL3 for cross-platform support
|
||||
|
||||
### Engine Entry Points
|
||||
- `source/prosperon.c` - Main C entry point
|
||||
- `scripts/core/engine.js` - JavaScript engine initialization for system
|
||||
- `scripts/core/base.js` has modifications to this Javascript runtime (for example, additions to the base Array, String, etc)
|
||||
|
||||
### Subprojects
|
||||
- C code has many subprojects, who's source and sometimes documentation can be found in subprojects. subprojects/quickjs/doc has documentation for quickjs
|
||||
|
||||
### Resource System
|
||||
- Scripts are bundled into `core.zip` during build
|
||||
- Runtime module loading via PhysFS
|
||||
- Resource paths checked in order: `/`, `scripts/modules/`, `scripts/modules/ext/`
|
||||
|
||||
### Notable Dependencies
|
||||
- QuickJS (custom build) - JavaScript runtime
|
||||
- SDL3 - Platform abstraction
|
||||
- Chipmunk2D - Physics
|
||||
- ENet - Networking
|
||||
- Soloud - Audio
|
||||
- Tracy - Profiling (when enabled)
|
||||
|
||||
## Development Tips
|
||||
|
||||
### Running Games
|
||||
```bash
|
||||
# Build first
|
||||
make debug
|
||||
|
||||
# Run example from build directory
|
||||
./build_dbg/prosperon examples/chess
|
||||
|
||||
# Or copy to game directory
|
||||
cp build_dbg/prosperon examples/chess/
|
||||
cd examples/chess
|
||||
./prosperon
|
||||
```
|
||||
|
||||
### Documentation
|
||||
- Documentation is found in docs
|
||||
- Documentation for the JS modules loaded with 'use' is docs/api/modules
|
||||
- .md files directly in docs gives a high level overview
|
||||
- docs/cell.md documents the Cell language (JavaScript variant used in Prosperon)
|
||||
|
||||
### Shader Development
|
||||
- Shaders are in `shaders/` directory as HLSL
|
||||
- Compile script: `shaders/compile.sh`
|
||||
- Outputs to platform-specific formats: `dxil/`, `msl/`, `spv/`
|
||||
|
||||
### Example Games
|
||||
Located in `examples/` directory:
|
||||
- `chess` - Chess implementation (has its own Makefile)
|
||||
- `pong` - Classic pong game
|
||||
- `snake` - Snake game
|
||||
- `tetris` - Tetris clone
|
||||
- `bunnymark` - Performance test
|
||||
|
||||
### Testing
|
||||
```bash
|
||||
# Run all tests
|
||||
meson test -C build_dbg
|
||||
|
||||
# Run specific test
|
||||
./build_dbg/prosperon tests/spawn_actor.js
|
||||
```
|
||||
|
||||
### Debugging
|
||||
- Use debug build: `make debug`
|
||||
- Tracy profiler support when enabled
|
||||
- Console logging available via `log.console()`, `log.error()`, etc.
|
||||
- Log files written to `.prosperon/log.txt`
|
||||
|
||||
# Project Structure Notes
|
||||
|
||||
## Core JavaScript Modules
|
||||
|
||||
- JavaScript modules are defined using the MISTUSE macro in jsffi.c
|
||||
- The `js_os_funcs`, `js_io_funcs`, etc. arrays define the available functions for each module
|
||||
- New functions are added with MIST_FUNC_DEF(module, function, args_count)
|
||||
|
||||
## File I/O
|
||||
|
||||
- `io.slurp(path)` - Reads a file as text
|
||||
- `io.slurp(path)` - Reads a file as an ArrayBuffer
|
||||
- `io.slurpwrite(path, data)` - Writes data (string or ArrayBuffer) to a file
|
||||
- `io.exists(path)` - Checks if a file exists
|
||||
|
||||
## Script Loading
|
||||
|
||||
- The `use(path)` function in engine.js loads JavaScript modules
|
||||
- Script loading happens in prosperon.c and the engine.js script
|
||||
- jsffi.c contains the C hooks for the QuickJS JavaScript engine
|
||||
- Added functionality for bytecode compilation and loading:
|
||||
- `os.compile_bytecode(source, filename)` - Compiles JS to bytecode, returns ArrayBuffer
|
||||
- `os.eval_bytecode(bytecode)` - Evaluates bytecode from an ArrayBuffer
|
||||
- `compile(scriptPath)` - Compiles a JS file to a .jso bytecode file
|
||||
- Modified `use()` to check for .jso files before loading .js files
|
||||
|
||||
## QuickJS Bytecode API
|
||||
|
||||
- `JS_Eval` with JS_EVAL_FLAG_COMPILE_ONLY - Compiles without executing
|
||||
- `JS_WriteObject` with JS_WRITE_OBJ_BYTECODE - Serializes to bytecode
|
||||
- `JS_ReadObject` with JS_READ_OBJ_BYTECODE - Deserializes and loads bytecode
|
||||
- Bytecode files use .jso extension alongside .js files
|
||||
|
||||
## Available JavaScript APIs
|
||||
|
||||
### Core APIs
|
||||
- `actor` - Base prototype for all actor objects
|
||||
- `$_` - Special global for actor messaging
|
||||
- `prosperon` - Global engine interface
|
||||
- `console` - Logging and debugging interface
|
||||
|
||||
### Rendering
|
||||
- `draw2d` - 2D drawing primitives
|
||||
- `render` - Low-level rendering operations
|
||||
- `graphics` - Higher-level graphics utilities
|
||||
- `camera` - Camera controls and transformations
|
||||
- `sprite` - Sprite rendering and management
|
||||
|
||||
### Physics and Math
|
||||
- `math` - Mathematical utilities
|
||||
- `geometry` - Geometric calculations and shapes
|
||||
- `transform` - Object transformations
|
||||
|
||||
### Input and Events
|
||||
- `input` - Mouse, keyboard, and touch handling
|
||||
- `event` - Event management system
|
||||
|
||||
### Networking
|
||||
- `enet` - Networking through ENet library
|
||||
- `http` - HTTP client capabilities
|
||||
|
||||
### Audio
|
||||
- `sound` - Audio playback using SoLoud
|
||||
|
||||
### Utility Modules
|
||||
- `time` - Time management and delays
|
||||
- **Must be imported with `use('time')`**
|
||||
- No `time.now()` function - use:
|
||||
- `time.number()` - Number representation of current time
|
||||
- `time.record()` - Struct representation of current time
|
||||
- `time.text()` - Text representation of current time
|
||||
- `io` - File I/O operations
|
||||
- `json` - JSON parsing and serialization
|
||||
- `util` - General utilities
|
||||
- `color` - Color manipulation
|
||||
- `miniz` - Compression utilities
|
||||
- `nota` - Structured data format
|
||||
- `wota` - Serialization format
|
||||
- `qr` - QR code generation/reading
|
||||
- `tween` - Animation tweening
|
||||
- `spline` - Spline calculations
|
||||
- `imgui` - Immediate mode GUI
|
||||
|
||||
## Game Development Patterns
|
||||
|
||||
### Project Structure
|
||||
- Game config is typically in `config.js`
|
||||
- Main entry point is `main.js`
|
||||
- Resource loading through `resources.js`
|
||||
|
||||
### Actor Pattern Usage
|
||||
- Create actors with `actor.spawn(script, config)`
|
||||
- Start actors with `$_.start(callback, script)` - the system automatically sends a greeting, callback receives {type: 'greet', actor: actor_ref}
|
||||
- No need to manually send greetings - `$_.start` handles this automatically
|
||||
- Manage actor hierarchy with overlings and underlings
|
||||
- Schedule actor tasks with `$_.delay()` method
|
||||
- Clean up with `kill()` and `garbage()`
|
||||
|
||||
### Actor Messaging with Callbacks
|
||||
When sending a message with a callback, respond by sending to the message itself:
|
||||
```javascript
|
||||
// Sender side:
|
||||
send(actor, {type: 'status'}, response => {
|
||||
log.console(response); // Handle the response
|
||||
});
|
||||
|
||||
// Receiver side:
|
||||
$_.receiver(msg => {
|
||||
if (msg.type === 'status') {
|
||||
send(msg, {status: 'ok'}); // Send response to the message itself
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
**Critical Rules for Message Callbacks**:
|
||||
- **A message can only be used ONCE as a send target** - after sending a response to a message, it cannot be used again
|
||||
- If you need to send multiple updates (like progress), only the download request message should be used for the final response
|
||||
- Status requests should each get their own individual response
|
||||
- Actor objects and message headers are completely opaque - never try to access internal properties
|
||||
- Never access `msg.__HEADER__` or similar - the actor system handles routing internally
|
||||
- Use `$_.delay()` to schedule work and avoid blocking the message receiver
|
||||
|
||||
### Game Loop Registration
|
||||
- Register functions like `update`, `draw`, `gui`, etc.
|
||||
- Set function.layer property to control execution order
|
||||
- Use `Register` system to manage callbacks
|
||||
|
||||
### Program vs Module Pattern
|
||||
- Programs are actor scripts that don't return values, they execute top-to-bottom
|
||||
- Modules are files that return single values (usually objects) that get frozen
|
||||
- Programs can spawn other programs as underlings
|
||||
- Programs have lifecycle hooks: awake, update, draw, garbage, etc.
|
||||
|
||||
## Technical Capabilities
|
||||
|
||||
### Graphics Pipeline
|
||||
- Supports multiple render backends (Direct3D, Metal, Vulkan via SDL3)
|
||||
- Custom shader system with cross-platform compilation
|
||||
- Sprite batching for efficient 2D rendering
|
||||
- Camera systems for both 2D and 3D
|
||||
|
||||
### Asset Support
|
||||
- Images: PNG, JPG, QOI, etc.
|
||||
- Audio: Various formats through SoLoud
|
||||
- Models: Basic 3D model support
|
||||
- Custom formats: Aseprite animations, etc.
|
||||
|
||||
### Developer Tools
|
||||
- Built-in documentation system with `cell.DOC`
|
||||
- Tracy profiler integration for performance monitoring
|
||||
- Imgui debugging tools
|
||||
- Console logging with various severity levels
|
||||
|
||||
## Misty Networking Patterns
|
||||
|
||||
Prosperon implements the Misty actor networking model. Understanding these patterns is critical for building distributed applications.
|
||||
|
||||
### Portal Reply Pattern
|
||||
Portals must reply with an actor object, not application data:
|
||||
```javascript
|
||||
// CORRECT: Portal replies with actor
|
||||
$_.portal(e => {
|
||||
send(e, $_); // Reply with server actor
|
||||
}, 5678);
|
||||
|
||||
// WRONG: Portal sends application data
|
||||
$_.portal(e => {
|
||||
send(e, {type: 'game_start'}); // This breaks the pattern
|
||||
}, 5678);
|
||||
```
|
||||
|
||||
### Two-Phase Connection Protocol
|
||||
Proper Misty networking follows a two-phase pattern:
|
||||
|
||||
**Phase 1: Actor Connection**
|
||||
- Client contacts portal using `$_.contact()`
|
||||
- Portal replies with an actor object
|
||||
- This establishes the communication channel
|
||||
|
||||
**Phase 2: Application Communication**
|
||||
- Client sends application messages to the received actor
|
||||
- Normal bidirectional messaging begins
|
||||
- Application logic handles game/service initialization
|
||||
|
||||
### Message Handling Best Practices
|
||||
Messages should be treated as opaque objects with your application data:
|
||||
|
||||
```javascript
|
||||
// CORRECT: Store actor references separately
|
||||
var players = {};
|
||||
$_.receiver(msg => {
|
||||
if (msg.type === 'join_game' && msg.player_id) {
|
||||
// Store the message for later response
|
||||
players[msg.player_id] = msg;
|
||||
// Later, respond to the stored message
|
||||
send(players[msg.player_id], {type: 'game_start'});
|
||||
}
|
||||
});
|
||||
|
||||
// WRONG: Trying to access internal message properties
|
||||
$_.receiver(msg => {
|
||||
var sender = msg.__HEADER__.replycc; // Never do this!
|
||||
});
|
||||
```
|
||||
|
||||
### Return ID Lifecycle
|
||||
- Each reply callback gets a unique return ID
|
||||
- Return IDs are consumed once and then deleted
|
||||
- Reusing message objects with return headers causes "Could not find return function" errors
|
||||
- Always create clean actor references for ongoing communication
|
||||
|
||||
|
||||
**Key Implementation Details:**
|
||||
- `actor_send()` in `scripts/core/engine.js` handles routing based on available actor data
|
||||
- Actor objects sent in message data automatically get address/port populated when received over network
|
||||
- Three communication pathways: `os.mailbox_exist()` check → mailbox send → network send
|
||||
- Actor objects must contain all necessary routing information for transparent messaging
|
||||
|
||||
### Common Networking Bugs
|
||||
1. **Portal sending application data**: Portal should only establish actor connections
|
||||
2. **Return ID collision**: Reusing messages with return headers for multiple sends
|
||||
3. **Mixed phases**: Trying to do application logic during connection establishment
|
||||
4. **Header pollution**: Using received message objects as actor references
|
||||
5. **Missing actor address info**: Actor objects in message data need network address population (fixed in engine.js:746-766)
|
||||
|
||||
### Example: Correct Chess Networking
|
||||
```javascript
|
||||
// Server: Portal setup
|
||||
$_.portal(e => {
|
||||
send(e, $_); // Just reply with actor
|
||||
}, 5678);
|
||||
|
||||
// Client: Two-phase connection
|
||||
$_.contact((actor, reason) => {
|
||||
if (actor) {
|
||||
opponent = actor;
|
||||
send(opponent, {type: 'join_game'}); // Phase 2: app messaging
|
||||
}
|
||||
}, {address: "localhost", port: 5678});
|
||||
|
||||
// Server: Handle application messages
|
||||
$_.receiver(e => {
|
||||
if (e.type === 'join_game') {
|
||||
opponent = e.__HEADER__.replycc;
|
||||
send(opponent, {type: 'game_start', your_color: 'black'});
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
## Memory Management
|
||||
|
||||
- When working with a conversational AI system like Claude, it's important to maintain a clean and focused memory
|
||||
- Regularly review and update memories to ensure they remain relevant and helpful
|
||||
- Delete or modify memories that are no longer accurate or useful
|
||||
- Prioritize information that can genuinely assist in future interactions
|
||||
Reference in New Issue
Block a user