tarinai/docs/prompt.txt
2026-06-23 11:27:55 +09:00

860 lines
No EOL
20 KiB
Text
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

Implement the new need-driven behavior system for the existing “tarinai” observation game.
Keep the implementation simple, localized, and compatible with the existing architecture. Do not perform a broad rewrite unless absolutely necessary.
Important source-code text rule:
All newly added Japanese UI strings or Japanese reason/action strings in source code must be written as Unicode escape sequences, not raw Japanese characters.
Example:
Do not write:
"あぶないけど、食べた。"
Write:
"\u3042\u3076\u306a\u3044\u3051\u3069\u3001\u98df\u3079\u305f\u3002"
Runtime text may display Japanese, but source literals must be escaped.
============================================================
GOAL
============================================================
Replace or absorb the existing detailed emotion-driven behavior system into a simple six-need system.
Behavior should be selected from six needs:
- food
- sleep
- health
- safety
- social
- fulfill
The system should allow imperfect behavior.
Example:
If safety and food are both maxed, the tarinai may randomly choose food and eat even though it is dangerous.
============================================================
1. SIX NEEDS
============================================================
Each tarinai should have:
needs = {
food: 0,
sleep: 0,
health: 0,
safety: 0,
social: 0,
fulfill: 0
};
Meaning:
food:
- eating
- drinking
sleep:
- sleep
- rest
- tiredness
health:
- illness
- injury
- dirt
- poison
- recovery
safety:
- danger
- fear
- ants
- explosions
- punches
- being attacked
social:
- friends
- parent/child
- mating/reproduction
- enemies if existing relation logic supports it
fulfill:
- play
- owned place
- owned structure
- grass bed
- plushie
- simple construction
Each need is internally 0100.
After raw calculation, quantize each value to 10-point steps:
0, 10, 20, ... 100
Use a helper like:
function quantizeNeed(value) {
return Math.max(0, Math.min(100, Math.round(value / 10) * 10));
}
For UI display, show only the tens digit:
0, 1, 2, ... 10
Example:
internal value 80 -> display 8
internal value 100 -> display 10
Safety is capped at 100 like every other need.
Safety is not a hard interrupt.
============================================================
2. NEED CALCULATION
============================================================
Calculate needs from existing tarinai/world state where possible.
Suggested mapping:
food:
- hunger
- thirst if available
sleep:
- low energy
- long awake time if available
- night/time-of-day bonus if available
health:
- disease
- injury
- dirtiness
- poison or negative status if available
safety:
- nearby ants
- nearby dangerous items
- recent damage
- fear/panic-related existing state if any
- being attacked
- owned structure destruction shock
social:
- loneliness if available
- nearby friend / parent / child
- reproduction readiness
- enemy proximity if current relation system supports it
fulfill:
- wants to play
- has no owned structure
- wants to return to owned grass bed
- wants to carry/use plushie
- wants to build a simple owned structure
Use existing personality fields if available:
aggression:
- safety rises slightly less from danger
- may choose intimidate instead of panic when there is a breaker/attacker
openness:
- fulfill rises more easily
- play/build actions become more likely
sociability:
- social rises more easily
- reacts less negatively when others use owned structures
neuroticism:
- safety and health rise more easily
- owned structure damage/destruction has stronger effect
Keep personality modifiers small and easy to tune.
============================================================
3. ACTION SELECTION
============================================================
Use this behavior flow:
1. Calculate all six raw needs.
2. Quantize all needs.
3. Find the maximum need value.
4. Collect all needs equal to the maximum.
5. Randomly choose one need from that tied top set.
6. Choose an executable action associated with that chosen need.
7. Store the chosen need and action in tarinai.intent.
8. Highlight only the chosen need in the tarinai data UI.
If safety and food are both 100, either may be chosen randomly.
Add helpers:
- createDefaultNeeds()
- quantizeNeed(value)
- updateNeeds(tarinai, world)
- chooseTopNeedRandom(needs)
- chooseActionForNeed(need, tarinai, world)
- buildReasonText(chosenNeed, tiedNeeds, action)
- getNeedDisplayValue(value)
============================================================
4. SIMPLE ACTION DEFINITIONS
============================================================
Use a simple action list, not a complex behavior tree.
Each action should have:
- id
- need
- label
- phrase
- weight
- condition(tarinai, world)
- run(tarinai, world)
Example shape:
const TARINAI_ACTIONS = [
{
id: "eat_food",
need: "food",
label: "\u98df\u3079\u7269\u3092\u63a2\u3057\u3066\u3044\u308b",
phrase: "\u98df\u3079\u305f",
weight: 50,
condition(t, world) {
return !!findNearestItemWithRole(world, t, "food");
},
run(t, world) {
const item = findNearestItemWithRole(world, t, "food");
moveToOrUse(t, item);
}
}
];
Suggested actions:
food:
- eat_food
- drink_water
sleep:
- sleep_in_bed
- sleep_in_owned_structure
- sleep_anywhere
health:
- use_medicine
- wash_or_drink_water
- rest_to_recover
safety:
- flee
- hide_in_nest
- hide_at_owned_structure
social:
- approach_friend
- approach_parent_or_child
- approach_mate
- intimidate_enemy
fulfill:
- play
- wander_lightly
- build_grass_bed
- build_plushie
- return_owned_structure
- use_plushie
Use weighted random among executable actions for the chosen need.
If no action is executable, fall back to idle, wander, or rest.
Do not make tarinai perfectly optimal.
============================================================
5. TIE REASON TEXT
============================================================
If multiple needs are tied for highest and the chosen need is only one of them, generate:
“[ignored need phrase]\u3051\u3069\u3001[chosen action phrase]\u3002”
Examples:
- "\u3042\u3076\u306a\u3044\u3051\u3069\u3001\u98df\u3079\u305f\u3002"
- "\u306d\u3080\u3044\u3051\u3069\u3001\u4ef2\u9593\u306b\u8fd1\u3065\u3044\u305f\u3002"
- "\u304a\u306a\u304b\u304c\u3059\u3044\u3066\u3044\u308b\u3051\u3069\u3001\u81ea\u5206\u306e\u5bdd\u5e8a\u3078\u623b\u3063\u305f\u3002"
- "\u8abf\u5b50\u304c\u60aa\u3044\u3051\u3069\u3001\u904a\u3093\u3060\u3002"
When multiple ignored needs exist, mention the ignored need with highest priority:
safety > health > food > sleep > social > fulfill
Conflict phrases:
food:
"\u304a\u306a\u304b\u304c\u3059\u3044\u3066\u3044\u308b"
sleep:
"\u306d\u3080\u3044"
health:
"\u8abf\u5b50\u304c\u60aa\u3044"
safety:
"\u3042\u3076\u306a\u3044"
social:
"\u3060\u308c\u304b\u304c\u6c17\u306b\u306a\u308b"
fulfill:
"\u81ea\u5206\u306e\u5834\u6240\u304c\u6c17\u306b\u306a\u308b"
If there is no tie, use:
“[need phrase]\u306e\u3067\u3001[action phrase]\u3002”
Store:
tarinai.intent = {
need: chosenNeed,
tiedNeeds,
actionId: action.id,
actionLabel: action.label,
reasonText
};
============================================================
6. NEED UI
============================================================
Update the tarinai data UI.
Show six needs as 010 values.
Labels must be escaped in source:
food label:
"\u6442\u990c"
sleep label:
"\u7761\u7720"
health label:
"\u5065\u5eb7"
safety label:
"\u5b89\u5168"
social label:
"\u95a2\u4fc2"
fulfill label:
"\u5145\u8db3"
Example UI:
摂餌 8
睡眠 3
健康 1
安全 10
関係 4
充足 10 ★
Only the need actually chosen for the current action receives the highlight.
Also show:
"\u3044\u307e":
[action label]
"\u7406\u7531":
[reasonText]
Do not show detailed need breakdowns.
Do not add graphs or extra panels.
============================================================
7. ITEM ROLES AND NEED EFFECTS
============================================================
Use minimal item roles and needEffects.
Do not create a broad tag system.
Item example:
item.roles = {
food: true,
drink: true,
medicine: true,
sleepPlace: true,
danger: true,
grassMaterial: true
};
item.needEffects = {
food: 0,
sleep: 0,
health: 0,
safety: 0,
social: 0,
fulfill: 0
};
Only add roles that are actually needed by the new behavior.
Useful helpers:
- findNearestItemWithRole(world, tarinai, role)
- findNearestSleepPlace(world, tarinai)
- findNearbyDanger(world, tarinai)
- findNearbyMaterial(world, tarinai, materialRole)
Adapt to existing item registries where possible.
============================================================
8. STRUCTURE REGISTRY
============================================================
Keep StructureRegistry because tarinai-built structures will expand in the future.
Do not collapse structures into one-off special item cases.
Create or adapt a small StructureRegistry for buildable tarinai structures.
Shared structure instance shape:
{
id,
type,
isStructure: true,
ownerId,
hp,
attachment,
usedCount,
x,
y,
roles,
needEffects
}
Do not implement:
- repair
- inheritance
- ownership privacy
- material-carrying inventory
- complex construction logistics
First buildable structures:
- grass_bed
- plushie
============================================================
9. STRUCTURE: GRASS BED
============================================================
Structure type:
"grass_bed"
Japanese label, escaped:
"\u8349\u306e\u7c21\u6613\u30d9\u30c3\u30c9"
Concept:
A simple bed made from grass. It is an owned place. The owner prefers it for sleep, safety, and fulfill.
Example registry entry shape:
grass_bed: {
type: "grass_bed",
label: "\u8349\u306e\u7c21\u6613\u30d9\u30c3\u30c9",
buildNeed: "fulfill",
buildTime: 4,
maxHp: 100,
materials: {
grassMaterial: 1
},
roles: {
sleepPlace: true,
ownedStructure: true
},
needEffects: {
food: 0,
sleep: 60,
health: 5,
safety: 25,
social: 0,
fulfill: 40
},
create(owner, x, y, world) {
return {
id: createId("structure"),
type: "grass_bed",
isStructure: true,
ownerId: owner.id,
hp: 100,
attachment: 20,
usedCount: 0,
x,
y,
roles: this.roles,
needEffects: this.needEffects
};
},
onUse(user, structure, world) {
// owner gets stronger effects
// non-owner gets weaker effects
// owner use increases attachment
},
onDestroyed(structure, world, breaker) {
// increase owner safety and fulfill
// trigger panic or intimidate through need shock logic
}
}
Build condition:
- chosen need is fulfill
- tarinai has no owned grass_bed
- grass material is nearby
- tarinai is not sleeping, fighting, or panicking
Build process:
- move near grass
- spend short build time if existing state system supports it
- consume/reduce grass if easy
- create grass_bed through StructureRegistry
Owner behavior:
- owner prefers own grass_bed for sleep, safety, and fulfill
- using own grass_bed reduces sleep, safety, and fulfill
- using own grass_bed increases attachment
Other tarinai:
- may use it with weaker effects
- if owner sees another tarinai using it:
- aggression may cause intimidate
- neuroticism may increase safety/fulfill
- sociability reduces negative reaction
Destruction:
- hp can be reduced by explosions, punches, weather, repeated use, or existing damage sources if easy to connect
- when hp reaches 0, call onDestroyed and remove structure
============================================================
10. STRUCTURE: PLUSHIE
============================================================
Add a new tarinai-built structure:
type:
"plushie"
Japanese label, escaped:
"\u306c\u3044\u3050\u308b\u307f"
Concept:
A small plushie item that resembles a tarinai. It is made from grass. When completed, it attaches to the owner tarinais head. While attached, it reduces fulfill. If damaged, it breaks and disappears. The owner receives a strong need shock and enters panic or intimidate.
Example registry entry shape:
plushie: {
type: "plushie",
label: "\u306c\u3044\u3050\u308b\u307f",
buildNeed: "fulfill",
buildTime: 4,
maxHp: 1,
materials: {
grassMaterial: 1
},
roles: {
carriedObject: true,
ownedStructure: true,
fulfillObject: true
},
needEffects: {
food: 0,
sleep: 0,
health: 0,
safety: 5,
social: 0,
fulfill: 50
},
create(owner, x, y, world) {
return {
id: createId("structure"),
type: "plushie",
isStructure: true,
ownerId: owner.id,
hp: 1,
attachment: 30,
usedCount: 0,
x,
y,
carriedById: owner.id,
onHead: true,
roles: this.roles,
needEffects: this.needEffects
};
},
onUse(user, structure, world) {
// if owner carries/uses it, reduce fulfill
// optionally reduce safety slightly
// increase attachment slightly
},
onDestroyed(structure, world, breaker) {
// large shock to owner safety and fulfill
// trigger panic or intimidate
}
}
Build condition:
- chosen need is fulfill
- tarinai does not already own/carry a plushie
- grass material is nearby
- tarinai is not sleeping, fighting, or panicking
Build process:
- move near grass
- spend short build time if existing state system supports it
- consume/reduce grass if easy
- create plushie through StructureRegistry
- attach it to owners head
Behavior while attached:
- follow owner position
- render above owners head
- use same or similar sprite as tarinai, scaled down
- reduce fulfill over time or when used
- optionally reduce safety slightly
- do not implement inventory
Damage/destruction:
- any meaningful damage destroys it
- remove plushie
- increase owner safety and fulfill strongly
- trigger panic or intimidate through need shock logic
Do not implement:
- repair
- inheritance
- trading
- inventory
- multiple plushies per tarinai
============================================================
11. EMOTION SYSTEM SIMPLIFICATION
============================================================
Remove the old detailed emotion system as a behavior driver.
Behavior must be selected only from the six needs:
food, sleep, health, safety, social, fulfill.
Old emotions should be removed or absorbed:
fear -> safety
loneliness -> social
happiness -> low stress / low fulfill pressure
sadness -> fulfill/social/safety pressure
comfort -> sleep/safety/fulfill satisfaction
boredom -> do not implement
anger -> intimidate state only
panic -> need shock reaction
stress -> derived pressure from needs
Do not keep happiness, sadness, fear, loneliness, comfort, boredom, or anger as independent behavior-driving values.
============================================================
12. STRESS REDEFINITION
============================================================
Stress is not an independent emotion.
Stress is a derived value calculated from current need pressure.
Do not directly add to stress for shock events.
For shock events, increase relevant needs first, then recalculate stress from needs.
Stress must not be used as a primary action-selection need.
Behavior is selected only from the six needs.
Stress may affect:
- expression
- minor visual intensity
- UI display if already present
- minor secondary effects if existing systems need it
Suggested pressure function:
function needPressure(value) {
const x = value / 100;
return x * x * 100;
}
Suggested stress calculation:
stress =
needPressure(food) * 0.10 +
needPressure(sleep) * 0.12 +
needPressure(health) * 0.25 +
needPressure(safety) * 0.30 +
needPressure(social) * 0.08 +
needPressure(fulfill) * 0.15;
Adjust weights if needed, but keep stress derived from needs.
============================================================
13. PANIC REDEFINITION
============================================================
Panic is not a need.
Panic is not a persistent emotion.
Panic is a short temporary reaction state caused by large sudden increases in safety, health, or fulfill.
Food, sleep, and social should not normally trigger panic.
Track previous needs or otherwise compute need delta.
Suggested rule:
panic triggers if:
- safety increases suddenly by 40 or more
- health increases suddenly by 45 or more
- fulfill increases suddenly by 50 or more
Panic should last for a short timer, such as 24 seconds.
After panic timer ends, return to normal need-based action selection.
If panic would be triggered and the tarinai has high aggression and a known breaker/attacker, use intimidate instead of panic.
Example:
if (shockTriggered) {
if (breaker && t.personality?.aggression > 0.6) {
t.state = "intimidate";
t.target = breaker;
} else {
t.state = "panic";
t.panicTimer = 3.0;
}
}
============================================================
14. EXPRESSION / VISUAL EMOTION COMPATIBILITY
============================================================
If the old emotion system is deeply tied to expressions, keep only a small compatibility layer for visuals.
Expressions should be derived from:
- current state
- chosen need
- stress level
- panic/intimidate
Suggested mapping:
state panic:
panic expression
state intimidate:
angry/threat expression
chosen need safety:
worried expression
chosen need food:
hungry expression
chosen need sleep:
sleepy expression
chosen need health:
unwell expression
chosen need social:
social/looking expression
chosen need fulfill:
neutral/pleased expression
Do not let old expression emotions drive behavior.
============================================================
15. SAVE COMPATIBILITY
============================================================
Backward compatibility is not required.
Do not implement save migrations.
Do not add compatibility shims for old saves unless the current code would immediately crash during normal startup.
It is acceptable if old saves are incompatible after this feature.
============================================================
16. DO NOT ADD
============================================================
Do not add:
- long-term memory
- boredom/habit system
- player-intervention profile
- ReactionRegistry
- WorldRules
- full behavior tree
- complex utility AI
- detailed need breakdown UI
- repair system
- inheritance system
- material-carrying inventory
- structure privacy system
============================================================
17. ACCEPTANCE CRITERIA
============================================================
After implementation:
- Each tarinai has six needs:
- food
- sleep
- health
- safety
- social
- fulfill
- Needs are clamped 0100.
- Needs are quantized to 10-point steps.
- UI displays needs as 010.
- Only the chosen action-driving need is highlighted.
- If multiple needs are tied for highest, one is chosen randomly.
- Safety does not force interruption.
- If safety and another need are tied, non-safety behavior can happen.
- Tie reason text uses the “Xけど、Yした。” format.
- Newly added Japanese source strings are Unicode escaped.
- Actions are defined in a simple action list.
- Items expose minimal roles and needEffects.
- StructureRegistry exists and supports at least grass_bed and plushie.
- grass_bed consumes grass to build.
- grass_bed is preferred by its owner.
- grass_bed destruction increases owner safety/fulfill and can trigger panic/intimidate.
- plushie consumes grass to build.
- plushie attaches to the owners head.
- plushie visually resembles a small tarinai.
- plushie reduces fulfill while carried/used.
- plushie breaks and disappears when damaged.
- plushie destruction strongly increases owner safety/fulfill and triggers panic/intimidate.
- Old detailed emotion values no longer drive behavior.
- Stress is derived from needs.
- Panic is caused by sudden safety/health/fulfill increases.
- Old save compatibility is not required.