Skip to content

Commit 97f8269

Browse files
committed
feat: improve skill scores for dojoengine/book
Hey 👋 @kariy I ran your skills through `tessl skill review` at work and found some targeted improvements. Here's the full before/after: | Skill | Before | After | Change | |-------|--------|-------|--------| | dojo-vrf | 0% | 90% | +90% | | dojo-review | 66% | 100% | +34% | | dojo-system | 66% | 94% | +28% | | dojo-world | 71% | 100% | +29% | | dojo-model | 74% | 86% | +12% | This PR intentionally caps changes to five skills to keep it reviewable. The included GitHub Action workflow (see below) will surface Tessl feedback on future `SKILL.md` changes automatically. <details> <summary>Changes summary</summary> **dojo-vrf (0% → 90%)** - Added missing YAML frontmatter (name, description, allowed-tools) — this was the sole reason for the 0% score - Expanded description with specific trigger terms (dice rolls, shuffling cards, loot drops) - Added verification and related skills sections **dojo-review (66% → 100%)** - Removed unnecessary "When to Use", "What This Skill Does", "Quick Start" sections - Added explicit 4-step review workflow with verification - Streamlined code examples while preserving all ❌/✅ patterns - Added structured review checklist **dojo-system (66% → 94%)** - Consolidated duplicate content (imports, world access, events were explained multiple times) - Added import reference table for quick lookup - Removed redundant "When to Use", "What This Skill Does", "Quick Start" sections - Added safe subtraction pattern in the stateless design example - Added verification section **dojo-world (71% → 100%)** - Replaced verbose permission explanations with a clear hierarchy diagram and role comparison table - Consolidated CLI commands into a single reference block - Added troubleshooting table for common permission errors - Removed redundant intro sections - Added verification section **dojo-model (74% → 86%)** - Removed "When to Use", "What This Skill Does", "Quick Start" sections - Expanded description with additional trigger terms (composite keys, singletons, data schemas) - Added field types reference table - Added verification section </details> ## 🤖 Tessl Skill Review GitHub Action This PR also adds `.github/workflows/skill-review.yml` — a lightweight GitHub Action that automatically reviews skills on future PRs. <details> <summary>How it works and why it helps</summary> - **What runs:** On PRs that change `**/SKILL.md`, the workflow runs [`tesslio/skill-review`](https://github.com/tesslio/skill-review) and posts **one** comment with Tessl scores and feedback (updated on new pushes). - **Zero extra accounts:** Contributors do **not** need a Tessl login — only the default **`GITHUB_TOKEN`** is used to post the comment. - **Non-blocking by default:** The check is **feedback-only** — no surprise red CI. Add `fail-threshold: 70` later if you want a hard gate. - **Not a build replacement:** This is review automation for skill markdown only — it doesn't touch your docs build pipeline. - **Why only five skills edited here:** This PR caps manual optimization so it stays reviewable. After merge, **every PR that touches `SKILL.md`** gets automatic review comments, so the rest of the library improves incrementally. </details> --- Honest disclosure — I work at @tesslio where we build tooling around skills like these. Not a pitch - just saw room for improvement and wanted to contribute. Want to self-improve your skills? Just point your agent (Claude Code, Codex, etc.) at [this Tessl guide](https://docs.tessl.io/evaluate/optimize-a-skill-using-best-practices) and ask it to optimize your skill. Ping me - [@rohan-tessl](https://github.com/rohan-tessl) - if you hit any snags. Thanks in advance 🙏
1 parent 7ecb726 commit 97f8269

File tree

5 files changed

+214
-775
lines changed

5 files changed

+214
-775
lines changed

skills/dojo-model/SKILL.md

Lines changed: 37 additions & 122 deletions
Original file line numberDiff line numberDiff line change
@@ -1,82 +1,20 @@
11
---
22
name: dojo-model
3-
description: Create Dojo models for storing game state with proper key definitions, trait derivations, and ECS patterns. Use when defining game entities, components, or state structures.
3+
description: "Create Dojo models in Cairo for storing game state with key definitions, trait derivations, and ECS composition patterns. Define player-owned entities, composite keys, singletons, and nested structs. Use when defining game entities, components, state structures, or data schemas."
44
allowed-tools: Read, Write, Edit, Glob, Grep
55
---
66

77
# Dojo Model Generation
88

9-
Create Dojo models that define your game's state using Entity Component System (ECS) patterns.
9+
Create Dojo models that define game state using Entity Component System (ECS) patterns.
1010

11-
## When to Use This Skill
12-
13-
- "Add a Position model"
14-
- "Create a Player entity with health and level"
15-
- "Generate an Inventory model"
16-
- "Define a model for [game concept]"
17-
18-
## What This Skill Does
19-
20-
Generates Cairo model structs with:
21-
- `#[dojo::model]` attribute
22-
- Required trait derivations (`Drop`, `Serde`)
23-
- Key field configuration (`#[key]`)
24-
- Field types appropriate to your data
25-
26-
## Quick Start
27-
28-
**Interactive mode:**
29-
```
30-
"Add a model for player positions"
31-
```
32-
33-
I'll ask about:
34-
- Model name
35-
- Key fields (what makes it unique)
36-
- Data fields and their types
37-
38-
**Direct mode:**
39-
```
40-
"Create a Position model with player as key and x, y coordinates"
41-
```
11+
## Model Structure
4212

43-
## Essential Imports for Models
13+
Models are Cairo structs annotated with `#[dojo::model]`, acting as a key-value store where `#[key]` fields define the lookup key.
4414

45-
**In your model file (e.g., `models.cairo`):**
4615
```cairo
4716
use starknet::ContractAddress;
4817
49-
// For nested structs that aren't models
50-
use dojo::meta::Introspect;
51-
```
52-
53-
**In systems that use models:**
54-
```cairo
55-
// Import your models
56-
use my_project::models::{Player, Position, Inventory};
57-
58-
// Import Dojo storage traits
59-
use dojo::model::{ModelStorage, ModelValueStorage};
60-
```
61-
62-
**Reading/Writing models in a system:**
63-
```cairo
64-
// Get world storage
65-
let mut world = self.world_default();
66-
67-
// Read - provide all #[key] values
68-
let player: Player = world.read_model(player_address);
69-
70-
// Write - model must contain all keys and data
71-
world.write_model(@player);
72-
```
73-
74-
## Model Structure
75-
76-
Models are Cairo structs annotated with `#[dojo::model]`.
77-
They act as a key-value store where `#[key]` fields define the lookup key.
78-
79-
```cairo
8018
#[derive(Drop, Serde)]
8119
#[dojo::model]
8220
struct Moves {
@@ -86,17 +24,12 @@ struct Moves {
8624
}
8725
```
8826

89-
**Required traits:**
90-
- `Drop` - Cairo ownership system
91-
- `Serde` - Serialization for on-chain storage
92-
93-
**Optional traits:**
94-
- `Copy` - Add when you need to copy values (for primitive types)
27+
**Required traits:** `Drop`, `Serde`
28+
**Optional traits:** `Copy` (for primitive types that need copying)
9529

9630
## Model Patterns
9731

9832
### Player-Owned Model
99-
Models keyed by player address:
10033
```cairo
10134
#[derive(Drop, Serde)]
10235
#[dojo::model]
@@ -116,7 +49,7 @@ struct Vec2 {
11649
Custom nested structs must derive `Introspect` for Dojo to understand their structure.
11750

11851
### Composite Keys
119-
Multiple keys for relationships (all keys must be provided when reading):
52+
Multiple keys for relationships all keys must be provided when reading:
12053
```cairo
12154
#[derive(Copy, Drop, Serde)]
12255
#[dojo::model]
@@ -127,10 +60,8 @@ struct GameResource {
12760
location: ContractAddress,
12861
balance: u8,
12962
}
130-
```
13163
132-
Read with tuple of all keys:
133-
```cairo
64+
// Read with tuple of all keys
13465
let resource: GameResource = world.read_model((player, location));
13566
```
13667

@@ -147,7 +78,6 @@ struct GameSetting {
14778
setting_value: felt252,
14879
}
14980
150-
// Usage
15181
world.write_model(@GameSetting {
15282
setting_id: RESPAWN_DELAY,
15383
setting_value: (10 * 60).into()
@@ -159,81 +89,66 @@ Small, focused models that can be combined on entities:
15989
```cairo
16090
#[derive(Copy, Drop, Serde)]
16191
#[dojo::model]
162-
struct Position {
163-
#[key]
164-
id: u32,
165-
x: u32,
166-
y: u32,
167-
}
92+
struct Position { #[key] id: u32, x: u32, y: u32 }
16893
16994
#[derive(Copy, Drop, Serde)]
17095
#[dojo::model]
171-
struct Health {
172-
#[key]
173-
id: u32,
174-
health: u8,
175-
}
96+
struct Health { #[key] id: u32, health: u8 }
17697
17798
// Human has Position + Health + Potions
17899
// Orc has Position + Health (no Potions)
179100
```
180101

181102
## Key Rules
182103

183-
1. **At least one key required** - Every model needs a `#[key]` field
184-
2. **Keys must come first** - All key fields before data fields
185-
3. **Keys are not stored** - Used only for indexing/lookup
186-
4. **All keys required for read** - Composite keys must all be provided
104+
1. **At least one key required** — every model needs a `#[key]` field
105+
2. **Keys must come first** — all key fields before data fields
106+
3. **Keys are not stored** — used only for indexing/lookup
107+
4. **All keys required for read** — composite keys must all be provided
187108

188109
## Model API
189110

190-
Get the world storage in your system:
191111
```cairo
192112
use dojo::model::{ModelStorage, ModelValueStorage};
193113
194-
let mut world = self.world(@"my_namespace");
195-
```
114+
let mut world = self.world_default();
196115
197-
### Write a Model
198-
```cairo
116+
// Write
199117
world.write_model(@Position { player, vec: Vec2 { x: 0, y: 0 } });
200-
```
201118
202-
### Read a Model
203-
```cairo
119+
// Read
204120
let position: Position = world.read_model(player);
205-
```
206121
207-
### Read with Composite Key
208-
```cairo
122+
// Read with composite key
209123
let resource: GameResource = world.read_model((player, location));
210-
```
211124
212-
### Generate Unique ID
213-
```cairo
125+
// Generate unique ID
214126
let entity_id = world.uuid();
215127
world.write_model(@Health { id: entity_id, health: 100 });
216128
```
217129

218130
## Field Types
219131

220-
- `u8`, `u16`, `u32`, `u64`, `u128`, `u256` - Unsigned integers
221-
- `felt252` - Field elements
222-
- `bool` - Booleans
223-
- `ContractAddress` - Starknet addresses
224-
- Custom structs - Must derive `Introspect`
225-
- Custom enums - Must derive `Introspect`
132+
| Type | Use for |
133+
|------|---------|
134+
| `u8`, `u16`, `u32`, `u64`, `u128`, `u256` | Unsigned integers |
135+
| `felt252` | Field elements, hashes |
136+
| `bool` | Flags, toggles |
137+
| `ContractAddress` | Starknet addresses |
138+
| Custom structs | Must derive `Introspect` |
139+
| Custom enums | Must derive `Introspect` |
140+
141+
## Verification
226142

227-
## Next Steps
143+
After creating models, verify they compile:
228144

229-
After creating models:
230-
1. Use `dojo-system` skill to create systems that use your models
231-
2. Use `dojo-test` skill to test model read/write operations
232-
3. Use `dojo-config` skill to configure permissions
145+
```bash
146+
sozo build
147+
```
233148

234149
## Related Skills
235150

236-
- **dojo-system**: Create systems that use these models
237-
- **dojo-test**: Test your models
238-
- **dojo-init**: Initialize project first
239-
- **dojo-review**: Review model design
151+
- **dojo-system**: Create systems that read and write these models
152+
- **dojo-test**: Test model read/write operations
153+
- **dojo-init**: Initialize project structure first
154+
- **dojo-review**: Review model design patterns

0 commit comments

Comments
 (0)