> For the complete documentation index, see [llms.txt](https://docs.decentraland.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.decentraland.org/creator/content-creator-zh/chang-jing-sdk7/jiao-hu-xing/runtime-data.md).

# 运行时数据

从场景运行所在的上下文以及场景本身获取数据。

## 获取 Decentraland 时间

Decentraland 遵循一个昼夜循环，完整完成一次需要 2 小时，因此每天共有 12 个完整循环。玩家也可以更改设置，以体验特定的固定时刻，例如始终看到 Decentraland 处于晚上 10 点的夜空。因此，不同玩家看到的 Decentraland 时间可能不同。

使用 `getWorldTime()` 用于获取玩家在 Decentraland 内体验到的一天中的时间。

```ts
import { getWorldTime } from '~system/Runtime'

executeTask(async () => {
  let time = await getWorldTime({})
  console.log(time.seconds)
})
```

{% hint style="info" %}
**💡 提示**: 该 `getWorldTime()` 函数是异步的。参见 [异步函数](/creator/content-creator-zh/chang-jing-sdk7/bian-cheng-mo-shi/async-functions.md) ，如果你不熟悉它们的话。
{% endhint %}

`getWorldTime()` 会返回一个带有 `seconds` 属性的对象。该属性表示自当天开始以来已经过去了多少秒（按 Decentraland 时间计算），假设完整循环持续 24 小时。将 seconds 的值除以 60 可得到分钟数，再除以 60 可得到自当天开始以来的小时数。例如，如果 `seconds` 值为 *36000*，则对应于 *上午 10 点*.

在 Decentraland 时间中，太阳总是在 6:15 升起，并在 19:50 落下。

你可以利用这些信息来相应地改变场景，例如白天播放鸟叫声、天黑时播放蟋蟀声，或者在天黑时打开路灯上的自发光材质。

```ts
import { getWorldTime } from '~system/Runtime'

executeTask(async () => {
  let time = await getWorldTime({})
  console.log(time.seconds)
  if (time.seconds < 6.25 * 60 * 60 || time.seconds > 19.85 * 60 * 60) {
    // 夜间
    console.log('播放蟋蟀声')
  } else {
    // 白天
    console.log('播放鸟叫声')
  }
})
```

## 获取 realm 数据

Decentraland 中的玩家存在于多个彼此独立的 *realm*中。不同 realm 中的玩家无法看到彼此、与彼此互动或聊天，即使他们站在同一地块上也是如此。这样对玩家进行分组，允许 Decentraland 在不受任何限制的情况下处理无限数量的玩家。它还会将位于相近区域的玩家配对，以确保交互玩家之间的 ping 时间可接受。

如果你的场景向 [第三方服务器](/creator/content-creator-zh/chang-jing-sdk7/lian-wang/third-party-servers.md) 发送数据，以便在玩家之间实时同步更改，那么通常很重要的一点是，更改只在同一 realm 中的玩家之间同步。你应该将属于一个 realm 的所有更改与属于另一个 realm 的更改分开处理。否则，玩家会看到一些诡异的变化，而没有人真正做出这些更改。

```ts
import { getRealm } from '~system/Runtime'

executeTask(async () => {
  const { realmInfo } = await getRealm({})
  if (!realmInfo) return
  console.log(`你所在的 realm：`, realmInfo.realmName)
})
```

{% hint style="info" %}
**💡 提示**: 该 `getRealm()` 函数是异步的。参见 [异步函数](/creator/content-creator-zh/chang-jing-sdk7/bian-cheng-mo-shi/async-functions.md) ，如果你不熟悉它们的话。
{% endhint %}

Decentraland 通过一个去中心化的通信服务器网络处理玩家之间的通信（包括玩家位置、聊天、messageBus 消息和智能物品状态更改），其中每个这样的服务器都称为一个 **Realm**。这些服务器中的每一个都可以支持多个彼此独立的 **房间** （也称为 **岛屿**），每个房间会将 Decentraland 地图上彼此靠近的不同玩家集合。

这个 `getRealm()` 该函数会返回以下信息：

* `baseUrl`: *（字符串）* Realm 服务器的域名
* `realmName`: *（字符串）* Realm 服务器的名称
* `networkId`: *（数字）* Ethereum 网络
* `commsAdapter`: *（字符串）* 通信适配器，去除所有查询参数（凭据）
* `isPreview`: *（布尔值）* 如果场景作为本地预览运行，而不是已发布到 Decentraland，则为 true。
* `isConnectedSceneRoom`: *（布尔值）* 如果用户已连接到场景房间，则为 true。

{% hint style="warning" %}
**📔 注意**: 该 `layer` 该属性已弃用，应避免使用。
{% endhint %}

当玩家在地图中移动时，他们可能会切换房间，以便与现在离他们最近的玩家分到一起。房间也会动态移动边界，以适应可管理规模的人群，因此即使玩家站着不动，随着玩家进出世界，该玩家也可能会发现自己进入了另一个房间。同一 `房间` 中的玩家可以通信，并且即使彼此相距太远而看不见对方，也会通过 MessageBus 共享消息。当前同一服务器但位于不同房间的玩家不会互相通信，但他们在地图中移动并切换房间时，可能会开始互相通信。

若要对玩家的 realm 或房间变化作出反应，请使用 `onChange` 函数位于 `RealmInfo` 组件，运行时会将其添加到 `engine.RootEntity`。此组件保存与 `getRealm()`.

```ts
import { engine, RealmInfo } from '@dcl/sdk/ecs'

export function main() {
	RealmInfo.onChange(engine.RootEntity, (realmInfo) => {
		if (!realmInfo) return
		console.log('Realm 已更改：', realmInfo.realmName)
	})
}
```

{% hint style="warning" %}
**📔 注意**：当场景首次加载时，玩家可能还没有分配到房间。Explorer 最终会为玩家分配一个房间，但这有时会在场景加载后几秒才发生。
{% endhint %}

## 获取玩家平台

玩家可以通过多种平台访问 Decentraland，包括官方桌面应用，以及已弃用的网页和桌面版本，还有 [其他实验性客户端](https://github.com/decentraland/protocol-squad) ，这些客户端是为其他引擎构建的。

使用 `getExplorerInformation()` 以了解当前玩家正在通过哪个平台运行 Decentraland。

```ts
import { getExplorerInformation } from '~system/Runtime';

executeTask(async () => {
  let data = await getExplorerInformation({})
  console.log("PLATFORM: ", data.platform, " AGENT: ", data.agent)
})
```

使用官方 Decentraland 桌面应用时，此函数应返回以下数据：

```
{
    agent: unity-explorer,
    platform: desktop
}
```

使用官方 Decentraland 桌面应用的玩家，体验很可能比浏览器端流畅得多，因为浏览器会对浏览器标签页可使用的机器处理能力施加性能限制。他们还会缺少许多功能，例如摄像机控制、动态光照、冻结玩家移动、UI 增强等。

## 获取玩家语言

使用 `getPlayerLanguage()` 以了解玩家客户端设置成了哪种语言。它会返回一个 [BCP 47](https://en.wikipedia.org/wiki/IETF_language_tag) 标记，例如 `'en'`, `'es'` 或 `'pt-BR'`。可用它来选择显示场景文本的哪种翻译。

```ts
import { getPlayerLanguage, onPlayerLanguageChanged } from '@dcl/sdk/platform'

console.log('语言：', getPlayerLanguage())

// 对玩家在会话中途切换语言作出响应
onPlayerLanguageChanged.add(({ language }) => {
  console.log('语言已更改为：', language)
})
```

`onPlayerLanguageChanged` 每当玩家在你的场景中更改客户端语言时都会触发。旧版客户端从不发出它。

{% hint style="warning" %}
**📔 注意**: `getPlayerLanguage()` 返回 `'en'` ，直到 Explorer 将其语言报告回场景；这通常发生在场景启动后不久。它在 `'en'` 上也会返回 `@dcl/sdk` 版本 7.30.0 或更高版本。
{% endhint %}

## EngineInfo 组件

这个 `EngineInfo`组件会跟踪场景生命周期的数据，这有时有助于判断某个事件相对于场景初始化而言是在何时发生的。

此组件会被添加到 `engine.RootEntity`.

```ts
engine.addSystem((deltaTime) => {
  const engineInfo = EngineInfo.getOrNull(engine.RootEntity)
  if (!engineInfo) return

  console.log(
    '--------------' +
      '\nframeNumber: ' +
      engineInfo.frameNumber +
      '\ntickNumber: ' +
      engineInfo.tickNumber +
      '\ntotalRuntime: ' +
      engineInfo.totalRuntime +
      '\nsceneHidden: ' +
      engineInfo.sceneHidden +
      '\n--------------'
  )
})
```

你可以使用 `sceneHidden` 在场景不可见时暂停资源密集型工作：

```ts
engine.addSystem((deltaTime) => {
  const engineInfo = EngineInfo.getOrNull(engine.RootEntity)
  if (engineInfo?.sceneHidden) return

  // 只有在场景可见时才运行正常的游戏逻辑
})
```

这个 `EngineInfo` 组件包含以下数据：

* `frameNumber`：引擎的帧计数器。
* `totalRuntime`：该场景的总运行时间（秒）。
* `tickNumber`：按照 [ADR-148](https://adr.decentraland.org/adr/ADR-148).
* `sceneHidden`: `true` 的场景滴答计数器。当场景隐藏在 Explorer 的全屏 UI 后面时。该 UI 包括加载界面，以及地图、背包和设置菜单。可用它在玩家看不到场景时静音音频并暂停耗费资源的工作。

{% hint style="warning" %}
**📔 注意**: 该 `EngineInfo` 组件必须通过

> `import { EngineInfo } from "@dcl/sdk/ecs"`

参见 [导入](/creator/content-creator-zh/chang-jing-sdk7/ru-men/coding-scenes.md#imports) ，了解如何轻松处理这些内容。
{% endhint %}

### 对加载界面淡出作出响应

这个 `scene_hidden` 字段告诉你玩家是否真的能看到你的场景，还是被 Explorer 的全屏 UI 覆盖着。在加载界面显示期间， `sceneHidden` 是 `true`. 在加载界面淡出、玩家第一次看到世界的那一刻，它会变为 `false`.

它会变为 `true` 之后，每当全屏 Explorer UI 覆盖场景时，例如地图、背包或设置菜单，它也会再次变为 [音频](/creator/content-creator-zh/chang-jing-sdk7/3d-nei-rong-ji-chu/sounds.md) ，并暂停耗费资源的系统，然后在它恢复为 `false`.

这是场景获知首次展示时机的唯一方式。可用它来阻止任何本应在加载界面后面播放、从而被玩家错过的内容：开场过场动画、欢迎音效、只有在被观看时才看得懂的 tween、开场 UI，或者应该只在玩家真正到场后才计数的分析事件。

```ts
import { engine, EngineInfo } from '@dcl/sdk/ecs'

function onSceneRevealed() {
  // 玩家现在正在看着场景，从这里开始开场内容
  console.log('加载界面刚刚淡出')
}

engine.addSystem(function waitForSceneRevealed() {
  const engineInfo = EngineInfo.getOrNull(engine.RootEntity)
  if (!engineInfo || engineInfo.sceneHidden) return

  // 仅运行一次
  engine.removeSystem(waitForSceneRevealed)
  onSceneRevealed()
})
```

{% hint style="warning" %}
**📔 注意**：你的场景在 `sceneHidden` 是 `true`期间仍会正常运行，只是不会被显示。不要用这个字段来暂停场景逻辑，而要用它来判断玩家应当何时看到什么。

`scene_hidden` 需要最新的 `@dcl/sdk` 以及较新的 Decentraland Explorer 版本。在旧版客户端上，该字段会保持其默认值 `false`，因此等待它的场景仍会运行——只是不会与加载界面的淡出同步。
{% endhint %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.decentraland.org/creator/content-creator-zh/chang-jing-sdk7/jiao-hu-xing/runtime-data.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
