Script Basics
This document assumes you have no programming foundation and will gradually explain concepts related to Yin.Story. If you already know JavaScript, you can directly jump to Yin.Object Extensions.
Script Language
Yin.Story relies on Yin.Object for construction, using JavaScript as the scripting language. We strive to reduce script complexity, allowing you to start scripting by understanding just a few basic concepts.
What is a Script?
Computers execute instructions line by line from scripts. For example:
Comments in Code
Gray text after // are comments explaining the next line. Comments are optional and not executed.
// Set three variables: money=529,900, faceScore=999999999999, liuruyanslove=false
let money = 529900, faceScore = 999999999999, liuruyanslove = false
// If money + faceScore > 100,000,000
if (money + faceScore > 100000000) {
// Set liuruyanslove to true
liuruyanslove = true
}
else {
// Set liuruyanslove to false
liuruyanslove = false
}What is an Object?
An object is a collection of data (variables) and functionality. For example:
// Create a 'me' object
let me = {
title: 'Xiao Ming',
money: 529900, // Assets
faceScore: 999999999999, // Appearance score
cp: 500, // Combat power
mate: null // No mate
}
// Create an NPC array containing two NPCs
let NPCList = [
{
title: 'Liu Ruyan',
money: 10000000,
faceScore: 99999999999,
cp: 10000
},
{
title: 'Ruhua',
money: 300,
faceScore: 5,
cp: 9999999999 // Combat power overflow!!
}
]
// If my assets + appearance score > 100,000,000
if (me.money + me.faceScore > 100000000) {
// My mate = Liu Ruyan
me.mate = 'Liu Ruyan'
// The following are optional code snippets
// Liu Ruyan is at the 0th index in NPCList (arrays use 0-based indexing)
// In programming, we primarily use array indices (starting from 0) to access elements
me.mate = 0
// Or assign the actual value
me.mate = NPCList[0]
}
// If the condition "my assets + my looks > 100000000" is not met
else {
// My partner = null
me.mate = null
}
// At this moment, Ruhua starts to forcibly take over and becomes my partner
// Create a variable called Ruhua, whose value is taken from the 1st element of the NPCList array (arrays use 0-based indexing)
// Ruhua is the 1st element in NPCList
let ruhua = NPCList[1]
// If my partner is null
if (me.mate === null) {
// If my combat power < Ruhua's combat power
if (me.cp < ruhua.cp) {
// My partner = Ruhua
me.mate = 'Ruhua'
}
}
// If "my partner is null" is not true
else {
// Create a variable called 'partner' and leave it unassigned for now
let mate
// Liu Ruyan is the 0th element in NPCList
// Assign the value of 'partner' from the 0th element of the NPCList array (arrays use 0-based indexing)
mate = NPCList[0]
// The following are optional code snippets
// If using the index of the array in the optional code snippet above - me.mate = 0
// Then the variable 'mate' can be assigned from the value at the index 'me.mate' in the NPCList array
mate = NPCList[me.mate]
// If using a specific value in the optional code snippet above - me.mate = NPCList[0]
// Then the variable 'mate' can be directly assigned from 'me.mate'
mate = me.mate
// In programming, we often use the optional code snippet approach because it supports more flexibility (e.g., multiple partners) rather than specifying Liu Ruyan explicitly
// If my combat power + my partner's (Liu Ruyan's) combat power < Ruhua's combat power
if (me.cp + mate.cp < ruhua.cp) {
// My partner = Ruhua 👍
me.mate = 'Ruhua'
}
}What is a Function?
A function is a collection of script instructions. For example, the companion judgment logic from the object section can be encapsulated into a reusable function.
In this system, functions are typically attached to objects. Example:
// Create an object called 'me' that contains multiple key-value pairs
let me = {
title: 'Xiao Ming',
money: 529900, // Assets
faceScore: 999999999999, // Appearance score
cp: 500, // Combat power
mate: null, // No mate
/**
* Make an NPC become my partner
* @param npc {Object} - Input is a character object
* @return {Object|null} - Output is the current partner or null
*/
beMyMate(npc) {
let ruhua = NPCList[1];
// If there is already a partner, and the partner is not Ruhua
// Note: When the function is attached to an object (as in this case), 'this' refers to the object 'me' within this function
if (this.mate !== null && this.mate !== ruhua) {
// Cannot change the partner, return the current partner as the output
return this.mate;
// The function ends here, and no further scripts are executed
}
// If my assets + my looks > npc's assets + npc's looks
if (this.money + this.faceScore > npc.money + npc.faceScore) {
// If my combat power + npc's combat power >= Ruhua's combat power
if (this.cp + npc.cp >= ruhua.cp) {
// My partner = npc
this.mate = npc;
// Return npc as the output
return npc;
// The function ends here, and no further scripts are executed
}
}
// If my assets + my looks > npc's assets + npc's looks is not true
// But if my combat power >= Ruhua's combat power
else if (this.cp >= ruhua.cp) {
// Break free from Ruhua's constraint, clear the partner
this.mate = null;
// Return null as the output
return null;
// The function ends here, and no further scripts are executed
}
// If the function reaches this point, Ruhua is forcibly bound as the partner
this.mate = ruhua;
// Return the character Ruhua as the output
return ruhua;
}
}Yin.Object Extension
The core of Yin.Story relies on Yin.Object for its construction. The data objects are extended from native JavaScript objects, adding features such as persistence and hot synchronization.
These changes also affect how child objects and arrays are accessed.
Due to persistence, Yin.Object assigns an address to each object. The object address can be found on the second line of the object panel when opened. Clicking the address will copy it, or you can right-click the object and select reference to copy the object address.
For example, the place of 片头 is Element.6964ae79ef2432c0cc8e8de3.
Objects in Yin
We can bind scripts to data objects to enhance their functionality. By clicking the plus sign next to the script in the editor, a script can be created and bound to the data object. At this point, the editor will generate JSDoc for the script to provide code hints.
Below is an explanation using the display condition of an event script from Yin.Story as an example:
// Script for an event object
export default {
// Event show condition
async show(save) {
// Get the target scene of this event
const scene = await this.target;
// Get the target scene by address, check the second line after opening the object
const target = await this._yin.get('Element.6964ae79ef2432c0cc8e8de3');
// Get the event list of the target scene
const events = await target.events;
// Retrieve the complete list
await events.all();
save.data.somevalue = 123;
// Save the story data
await save._save();
// Save this event, but since the player does not have permission to manage this event, this will throw an error.
await this._save();
}
}Congratulations!
You've completed all foundational knowledge for scripting in Yin.Story. The next guide will teach practical operations.