You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: AGENTS.md
+6-1Lines changed: 6 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -2,10 +2,15 @@
2
2
3
3
Mibo.Raylib is a port of the Mibo micro-framework from MonoGame to raylib-cs, designed to allow F# developers to write games using familiar patterns for all kinds of game genres and sizes.
4
4
5
-
Mibo aims to solve 90% of use cases for enabling developers to focus on game logic rather than boilerplate code, providing guidelines and architecture for structuring game code, handling input, rendering, asset management, and time management among others.
5
+
Mibo aims to solve 90% of use cases for enabling developers to focus on game logic rather than boilerplate code, providing guidelines and architecture for structuring game game code, handling input, rendering, asset management, and time management among others.
6
6
7
7
General setup and usage instructions can be found in the [README.md](README.md) file.
8
8
9
+
## Imperatives
10
+
11
+
1.**NEVER PUSH WITHOUT PERMISSION.** Always ask before pushing to the remote.
12
+
2.**Always run `dotnet fantomas .` before committing code.** Format all F# files before staging.
Mibo.Raylib uses raylib's built-in camera types for both 2D and 3D rendering:
10
+
Cameras control what part of the world you see and how it maps to the screen. Mibo.Raylib provides `Camera2D` for 2D games and `Camera3D`for 3D games. Both support single-camera, split-screen, and overlay patterns.
The 2D renderer consumes cameras via `Draw.beginCamera`. The `Camera3D` module provides helpers that produce a renderer-agnostic `Camera` struct (view + projection matrices) for use with the 3D pipeline.
14
+
-**Scroll and zoom** — A 2D camera lets your game world be larger than the screen. Pan, zoom, and follow a player.
15
+
-**Perspective** — A 3D camera defines where you look from and where you look at.
16
+
-**Coordinate conversion** — Convert between screen pixels and world positions for mouse picking, UI placement, and debug tools.
17
+
-**Multi-camera** — Split-screen multiplayer, picture-in-picture minimaps, and HUD overlays on top of the game world.
16
18
17
-
Both 2D and 3D cameras support config-based rendering via `Camera2DConfig` and `Camera3DConfig`, enabling viewport-based rendering, split-screen, and overlay patterns.
19
+
## When to use
18
20
19
-
## 2D cameras (`Camera2D`)
21
+
| Situation | Use |
22
+
|-----------|-----|
23
+
| 2D game with scrolling world |`Camera2D.create` + `Draw.beginCamera`|
24
+
| 2D game with split-screen or HUD |`Camera2DConfig` + `Draw.beginCameraWith`|
25
+
| 3D game |`Camera3D` struct + `Draw3D.beginCamera`|
26
+
| 3D split-screen or overlay |`Camera3DConfig` + `Draw3D.beginCameraWith`|
27
+
| Mouse picking in 3D |`Camera3D.screenPointToRay`|
In the Mibo.Raylib 2D renderer, you use `Draw.beginCamera` with raylib's `Camera2D` struct:
36
+
`Camera2D.create` centers the camera on a world position:
32
37
33
38
```fsharp
34
39
let camera = Camera2D.create (Vector2(400f, 300f)) 1.0f viewportSize
40
+
```
41
+
42
+
-`position` — world position to center on
43
+
-`zoom` — zoom factor (`1.0f` = no zoom)
44
+
-`viewportSize` — screen size in pixels (used to compute the offset)
45
+
46
+
### Using in a view
35
47
48
+
Wrap your world-space draw commands between `beginCamera` and `endCamera`. The `layer` parameter controls draw order — camera and content must share the same layer range.
Convert between screen pixels and world positions:
76
+
77
+
```fsharp
78
+
// Mouse click in world space
79
+
let worldPos = Camera2D.screenToWorld camera mousePos
80
+
81
+
// Where does a world object appear on screen?
82
+
let screenPos = Camera2D.worldToScreen camera enemyPos
83
+
```
84
+
85
+
Use `viewportBounds` to get the visible world rectangle — useful for culling off-screen objects:
54
86
55
87
```fsharp
56
-
type Camera = {
57
-
View: Matrix4x4
58
-
Projection: Matrix4x4
59
-
}
88
+
let visible = Camera2D.viewportBounds camera screenWidth screenHeight
60
89
```
61
90
62
-
### `Camera3D` module helpers
91
+
---
92
+
93
+
## 2D multi-camera
94
+
95
+
`Camera2DConfig` lets you control viewport, clear color, and rendering behavior per camera. Build one with `Camera2D.render` and chain `with*` modifiers.
63
96
64
-
> These helpers produce a renderer-agnostic `Camera` struct. Use them with `Draw3D.beginCamera` or store for later.
97
+
### Config modifiers
98
+
99
+
| Modifier | Description |
100
+
|----------|-------------|
101
+
|`Camera2D.withViewport rect`| Viewport in normalized screen coordinates (0–1) |
102
+
|`Camera2D.withClear color`| Clear with this color before rendering |
103
+
104
+
### Using a config in a view
65
105
66
106
```fsharp
67
-
// Look-at camera
68
-
let cam = Camera3D.lookAt
69
-
(Vector3(0f, 10f, 20f)) // position
70
-
Vector3.Zero // target
71
-
Vector3.Up // up
72
-
(MathF.PI / 4.0f) // 45° FOV
73
-
(16f / 9f) // aspect ratio
74
-
0.1f // near plane
75
-
1000f // far plane
76
-
77
-
// Orbit camera
78
-
let orbiting = Camera3D.orbit target yaw pitch radius fov aspect near far
79
-
80
-
// Screen-to-ray picking
81
-
let ray = Camera3D.screenPointToRay camera mousePos screenWidth screenHeight
107
+
let config =
108
+
Camera2D.render worldCamera
109
+
|> Camera2D.withClear Color.CornflowerBlue
110
+
111
+
buffer
112
+
|> Draw.beginCameraWith 0<RenderLayer> config
113
+
|> // ... world content ...
114
+
|> Draw.endCamera 999<RenderLayer>
82
115
```
83
116
84
-
### Camera3D rendering config
117
+
### Split-screen
85
118
86
-
`Camera3DConfig` controls viewport, clear color, and post-processing per camera. Use `Camera3D.render` to create one, then chain `with*` modifiers:
119
+
Pre-built helpers for two-player split-screen. Each clears with the given color.
For 3D rendering, create a `Camera3D` (raylib struct) directly. This is what `Draw3D.beginCamera` and `Camera3D.render` expect:
168
+
169
+
```fsharp
170
+
let camera = Camera3D(
171
+
Vector3(0f, 10f, 20f), // position
172
+
Vector3.Zero, // target
173
+
Vector3.UnitY, // up
174
+
45.0f, // FOV in degrees
175
+
CameraProjection.Perspective
176
+
)
177
+
```
178
+
179
+
For third-person or inspection cameras, use `Camera3D.orbit` which returns a `Camera3D` via spherical coordinates:
180
+
181
+
```fsharp
182
+
let orbitCam = Camera3D.orbit target yaw pitch radius fov aspect near far
183
+
```
184
+
185
+
> _**NOTE**_: `Camera3D.lookAt` and `Camera3D.orbit` return a `Camera` struct (view + projection matrices). This is useful for ray casting (`Camera3D.screenPointToRay`) but not for rendering. For rendering, create `Camera3D` directly or use `Camera3D.render` to build a config.
0 commit comments