default paintings
This commit is contained in:
parent
06176fb2d5
commit
43b659b64b
8 changed files with 4244 additions and 46 deletions
36
DEFAULT_ART_AUDIT.md
Normal file
36
DEFAULT_ART_AUDIT.md
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
# Default Art Audit
|
||||
|
||||
## 実施内容
|
||||
|
||||
`app.js` の `buildDefaultGalleryPack()` を確認し、初期同梱作品の品質を監査した。低品質または初期作品として弱いものは、削除対象リストで除外する方式にした。既存ローカル状態に残っている Island Team 製の該当作品も、次回ロード時に Collection / island placement / dynamic summon から除外される。
|
||||
|
||||
## 削除した初期作品
|
||||
|
||||
| 作品名 | 理由 |
|
||||
|---|---|
|
||||
| Shell Rock | 16×16に対して実質的な形状が小さく、島上で石・貝の識別点が弱い。 |
|
||||
| Azure Minnow | 魚としての頭・尾・ヒレが弱く、単なる水色の塊に近い。 |
|
||||
| Firefly Swirl | 8×8で透明部が多く、作品というより粒子エフェクトに近い。 |
|
||||
| Leaf Sparrow | 鳥のシルエットが薄く、頭・翼・尾の分離が不足している。 |
|
||||
| Silver Trout | 魚としては読めるが、既存の Cloud Koi / Sunset Koi より低密度で初期作品として弱い。 |
|
||||
| Butterfly Fish | 小型魚としての情報量が少なく、島上で主題が読み取りにくい。 |
|
||||
|
||||
## 残したが改変候補に入る作品
|
||||
|
||||
| 作品名 | コメント |
|
||||
|---|---|
|
||||
| River Stones | 8×8としては成立しているが、石の影と水際の情報を足すと良い。 |
|
||||
| Paper Crane | モチーフは明確だが、分断セルが多い。羽根の接続を調整できる。 |
|
||||
| Linen Cottage | 読みやすいが、屋根と壁の面が単純。影と窓を増やせる。 |
|
||||
| Human 系小型作品 | 役割差はあるが、体型・顔・道具の差分が弱いものがある。 |
|
||||
|
||||
## コード上の変更点
|
||||
|
||||
- `REMOVED_LOW_QUALITY_SEED_ASSET_NAMES` を追加。
|
||||
- `buildDefaultGalleryPack()` の戻り値に品質フィルタを適用。
|
||||
- `mergeDefaultGallery()` で既存ローカル状態の Island Team 製削除対象も除外。
|
||||
- Python 側テストは `14 passed`。
|
||||
|
||||
## 次の作業
|
||||
|
||||
ユーザー確認後、新しいデフォルト作品を追加する。追加時は `PIXEL_ART_QUALITY.md` の基準に従い、既存の弱いカテゴリを補う。
|
||||
35
DEFAULT_ART_EXPANSION.md
Normal file
35
DEFAULT_ART_EXPANSION.md
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
# Default Art Expansion / Depth Lighting Tuning
|
||||
|
||||
## Depth tuning
|
||||
|
||||
Adjusted the depth-local light response so that:
|
||||
|
||||
- local light influence stays colorized instead of washing into a neutral gray band,
|
||||
- the light source itself and nearby sprite/depth corners catch the strongest highlight,
|
||||
- brightness depends less on raw source-to-pixel distance than before,
|
||||
- convex edges still read clearly under nearby inspection/night lights.
|
||||
|
||||
Implementation areas: `depthLocalLightResponse()`, `getDepthEdgeLightBoost()`, and local-light color mixing inside `shadeAssetPixelColor()` in `app.js`.
|
||||
|
||||
## UI bubble correction
|
||||
|
||||
- Reduced the selection bubble top offset so the bubble appears closer to the selected sprite.
|
||||
|
||||
## New large default works
|
||||
|
||||
### Static / building
|
||||
- Smile Portrait — 24x32
|
||||
- Rosetta Stela — 24x32
|
||||
- Pharaoh Mask — 24x32
|
||||
- Terracotta Sentinel — 20x32
|
||||
|
||||
### Static / nature
|
||||
- Great Wave Panel — 32x24
|
||||
- Sunflower Still Life — 24x32
|
||||
- Stone Circle — 32x24
|
||||
|
||||
## Notes
|
||||
|
||||
- `assets.json` and `default_assets_sheet.png` were refreshed.
|
||||
- The seeded island placement list was expanded so these works appear by default.
|
||||
- Save schema was bumped to `25`.
|
||||
69
PIXEL_ART_QUALITY.md
Normal file
69
PIXEL_ART_QUALITY.md
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
# ドット絵品質基準 / Pixel Art Quality Standard
|
||||
|
||||
このプロトタイプで「良質なドット絵」と見なす基準。共有サービスの初期作品、審査、改変、削除判断で使う。
|
||||
|
||||
## 1. 最低条件
|
||||
|
||||
- **透明セルを作品の一部として設計している**:余白はただの空きではなく、シルエットを読ませるために残す。
|
||||
- **1秒以内に主題が判別できる**:縮小表示、島上表示、夜間表示でも「家」「鳥」「魚」「橋」などの役割が読める。
|
||||
- **接地・重心が明確**:静物は地面や水面に乗って見える。動物・人は足元または接地点が曖昧でない。
|
||||
- **パレットに収まる**:任意色の多用ではなく、既存パレットコードに近い色で統一する。
|
||||
- **クリック対象として破綻しない**:極端に薄い線、孤立点だけの作品、透明部分が多すぎる作品は避ける。
|
||||
|
||||
## 2. 具体的な評価軸
|
||||
|
||||
| 評価軸 | 良い状態 | 低品質と判断する状態 |
|
||||
|---|---|---|
|
||||
| シルエット | 背景なしでも輪郭だけで主題が読める | 点・棒・塊にしか見えない |
|
||||
| 明暗 | 上面・側面・影の方向がある | 全面が同じ明度で平坦 |
|
||||
| 色数 | 小物は3〜6色、中型は5〜10色程度で役割が分かれる | 1〜2色だけ、または無秩序に多色 |
|
||||
| ピクセル密度 | 余白、密部、抜きのバランスがある | ほぼ空白、またはベタ塗りの矩形 |
|
||||
| エッジ | 角、段差、斜線に意図がある | ガタつきが偶然に見える |
|
||||
| 内部ディテール | 目、窓、葉、波、道具など識別点がある | 主題を補強する点がない |
|
||||
| 島との親和性 | 地形、昼夜、他作品のサイズ感と合う | 尺度が浮く、接地しない、光源が不自然 |
|
||||
| メタ情報 | building の door、light、depth、particle が主題に沿う | メタ情報がない、または見た目と矛盾する |
|
||||
|
||||
## 3. サイズ別の合格目安
|
||||
|
||||
### 8×8
|
||||
|
||||
- 主題は1つに絞る。
|
||||
- 色は3〜5色までを目安にする。
|
||||
- 透明を含めても、主題の有効ピクセルは概ね16セル以上ほしい。
|
||||
- 「点の集合」ではなく、頭・胴・尾、花・葉・茎などの構造を最低2部位に分ける。
|
||||
|
||||
### 12×12〜16×16
|
||||
|
||||
- デフォルト作品の中心サイズ。
|
||||
- 輪郭色、主色、中間色、ハイライト、影の5層を基本にする。
|
||||
- 動物・人は顔または進行方向が読めること。
|
||||
- 建物・自然物は接地線、屋根/幹/水面などの基礎形を入れる。
|
||||
|
||||
### 20×20以上
|
||||
|
||||
- 大型作品はディテール量だけでなく、遠目の大形状を優先する。
|
||||
- 3〜5個の大きな面に分け、その中に小ディテールを置く。
|
||||
- 光・depth・particle を使う場合、効果が主題を補強していること。
|
||||
|
||||
## 4. 削除・改変の判断
|
||||
|
||||
### 削除候補
|
||||
|
||||
- 何を描いたか判別できない。
|
||||
- 既存の高品質作品と役割が重複し、見劣りする。
|
||||
- ほぼ点、線、単色塊で、改変より作り直しが早い。
|
||||
- 島上でクリックや配置の視認性を落とす。
|
||||
|
||||
### 改変候補
|
||||
|
||||
- 主題は読めるが、明暗・輪郭・接地が弱い。
|
||||
- 色の階調が足りない。
|
||||
- サイズに対してディテールが不足している。
|
||||
- 良いアイデアはあるが、他作品群と密度が合っていない。
|
||||
|
||||
## 5. デフォルト作品としての追加基準
|
||||
|
||||
- 初回表示でサービスの品質水準を示せること。
|
||||
- ユーザーがリミックスしたくなる明確なモチーフを持つこと。
|
||||
- 小型、中型、大型、静物、動物、人、船、水辺、建物が偏りすぎないこと。
|
||||
- 低品質作品を大量に残して作品数を稼がないこと。
|
||||
25
README.md
25
README.md
|
|
@ -298,3 +298,28 @@ Use this to compare minified JSON, gzip, zlib, and Brotli when available. Produc
|
|||
- Added server-side `world.phase` and `dynamic.move` event helpers/tests. Shared clients should treat these events as the source of truth for day/night and autonomous dynamic positions.
|
||||
- Pending shared object moves now render as temporary local interpolation only; the persistent world state is updated only by server-issued events.
|
||||
- Depth shading can now use a cursor-local light source on rendered sprites at night.
|
||||
|
||||
## Custom update 3: colored local light fix + heritage/masterpiece gallery
|
||||
|
||||
- Save schema is now `25`.
|
||||
- Fixed the local depth-light wash so the affected area no longer collapses into a mostly gray band; local lights now preserve more of the source color.
|
||||
- Reworked depth local-light behavior so the source itself and nearby outer/depth corners catch the strongest highlights, while distance has a weaker effect on brightness than before.
|
||||
- Reduced the selection bubble offset so the bubble sits noticeably closer to the top of the selected artwork.
|
||||
- Added several new large default works themed around masterpieces, heritage, and artifacts: **Smile Portrait**, **Great Wave Panel**, **Sunflower Still Life**, **Rosetta Stela**, **Pharaoh Mask**, **Stone Circle**, **Terracotta Sentinel**.
|
||||
- Refreshed `assets.json` and `default_assets_sheet.png` after the additions.
|
||||
|
||||
## Custom update 4: cursor-light smoothing + gray-bloom hotfix
|
||||
|
||||
- Save schema is now `26`.
|
||||
- Fixed the urgent regression where a single local light could wash large parts of a sprite into a gray, low-chroma bloom.
|
||||
- Reduced local-light body fill on depth sprites so highlights stay concentrated on lit edges / corners instead of flattening the whole silhouette.
|
||||
- Smoothed cursor-light falloff so in-range / out-of-range transitions are less abrupt.
|
||||
- Removed the always-on center fallback for the cursor inspection light and softened the visible cursor halo, which eliminates the unwanted blue circular artifact when no pointer light should be shown.
|
||||
|
||||
## Custom update 5: asset-light gray fix + temporary global delete + more default works
|
||||
|
||||
- Save schema is now `27`.
|
||||
- Adjusted **asset-mounted local lights** again so they no longer wash large depth sprites into a gray body fill; their effect is concentrated much more strongly on lit edges and corners.
|
||||
- Fixed the analog clock hand offset (it had been visually about 5 degrees early).
|
||||
- Added a **temporary** delete override so **all collection works can be deleted** regardless of owner. This is clearly marked in `app.js` with comments and can be reverted by setting `TEMP_ALLOW_DELETE_ALL_WORKS = false`.
|
||||
- Added many more default works: **Rain Bell Tower**, **Crimson Pagoda**, **Meteor Forge**, **Ink Garden Screen**, **Meadow Totem**, **Twilight Caravan**, **Pepper Fox**, **Glass Manta**, **Festival Drummer**, **Bloom Sprite**.
|
||||
|
|
|
|||
2815
assets.json
Normal file
2815
assets.json
Normal file
File diff suppressed because it is too large
Load diff
BIN
default_assets_sheet.png
Normal file
BIN
default_assets_sheet.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 128 KiB |
24
extract_assets.js
Normal file
24
extract_assets.js
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
const fs = require('fs');
|
||||
const vm = require('vm');
|
||||
const path = require('path');
|
||||
let code = fs.readFileSync(path.join(__dirname, 'app.js'), 'utf8');
|
||||
code = code.replace(/\n\s*bootstrap\(\);\s*\n\}\)\(\);\s*$/, `\n window.__PIXEL_DEBUG__ = { state, buildDefaultGalleryPack, PALETTE, PALETTE_BY_CODE, assetWidth, assetHeight };\n})();`);
|
||||
function makeCtx(){
|
||||
const noop=()=>{};
|
||||
return new Proxy({imageSmoothingEnabled:false, canvas:{width:1,height:1}}, {get(t,p){
|
||||
if(p in t) return t[p];
|
||||
if(p==='measureText') return () => ({width:0});
|
||||
return noop;
|
||||
}, set(t,p,v){ t[p]=v; return true; }});
|
||||
}
|
||||
function makeEl(id){ return new Proxy({ id, width:640, height:480, style:{}, classList:{add(){},remove(){},toggle(){},contains(){return false;}}, dataset:{}, value:'', checked:false, textContent:'', innerHTML:'', append(){}, appendChild(){}, addEventListener(){}, removeEventListener(){}, setAttribute(){}, removeAttribute(){}, focus(){}, blur(){}, getBoundingClientRect(){return {left:0,top:0,width:640,height:480};}, getContext(){return makeCtx();}, querySelector(){return makeEl('q');}, querySelectorAll(){return [];}}, {get(t,p){ if(p in t) return t[p]; if(p==='children') return []; return undefined; }, set(t,p,v){ t[p]=v; return true; }}); }
|
||||
const localStorage = { getItem(){return null;}, setItem(){}, removeItem(){} };
|
||||
const sandbox = { console, window: {}, document: { getElementById: makeEl, createElement: makeEl, querySelector(){return makeEl('q')}, querySelectorAll(){return []}, addEventListener(){}, body: makeEl('body')}, localStorage, performance: { now: () => 0 }, Math, Date, Map, Set, Array, Object, JSON, Number, String, Boolean, RegExp, Error, Uint8Array, Int8Array, Uint16Array, URL: {createObjectURL(){return ''}, revokeObjectURL(){}}, Blob: function(){}, Image: function(){}, FileReader: function(){}, requestAnimationFrame(){}, cancelAnimationFrame(){}, setTimeout, clearTimeout, structuredClone: global.structuredClone };
|
||||
sandbox.window = Object.assign(sandbox.window, { PixelIslandModules:{}, devicePixelRatio:1, addEventListener(){}, removeEventListener(){}, matchMedia(){return {matches:false, addEventListener(){}, removeEventListener(){}}}, requestAnimationFrame(){}, cancelAnimationFrame(){}, document: sandbox.document, localStorage: sandbox.localStorage });
|
||||
vm.createContext(sandbox);
|
||||
vm.runInContext(code, sandbox, {filename:'app.js'});
|
||||
const debug = sandbox.window.__PIXEL_DEBUG__;
|
||||
const assets = debug.state.assets.map(a => ({id:a.id,name:a.name,category:a.category,subtype:a.subtype,width:a.width,height:a.height,pixels:a.pixels,faces:a.faces,meta:a.meta,contentHash:a.contentHash}));
|
||||
fs.writeFileSync(path.join(__dirname,'assets.json'), JSON.stringify(assets,null,2));
|
||||
console.log('assets', assets.length);
|
||||
console.log(assets.map(a=>`${a.name} ${a.width}x${a.height} ${a.category}/${a.subtype}`).join('\n'));
|
||||
Loading…
Add table
Add a link
Reference in a new issue