gamemaker-expert

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

GameMaker Expert

GameMaker专家

Overview

概述

This skill provides comprehensive GameMaker Studio 2 and GML (GameMaker Language) expertise for all GameMaker projects. It covers everything from basic object creation to advanced topics like shader programming, networking, and platform-specific development.
When to use this skill:
  • Working with
    .gml
    files (GML scripts and events)
  • Creating or modifying
    .yy
    files (object definitions, sprite definitions, etc.)
  • Editing
    .yyp
    project files
  • Creating GameMaker objects, scripts, or assets
  • Debugging GameMaker compile errors or runtime issues
  • Implementing GameMaker features (drawing, collision, networking, etc.)
  • Optimizing GameMaker performance
  • Any GameMaker Studio 2 development task
本技能为所有GameMaker项目提供全面的GameMaker Studio 2与GML(GameMaker语言)相关专业指导,内容覆盖从基础对象创建到着色器编程、网络开发、平台专属开发等进阶主题。
何时使用本技能:
  • 处理
    .gml
    文件(GML脚本与事件)
  • 创建或修改
    .yy
    文件(对象定义、精灵定义等)
  • 编辑
    .yyp
    项目文件
  • 创建GameMaker对象、脚本或资源
  • 调试GameMaker编译错误或运行时问题
  • 实现GameMaker功能(绘图、碰撞检测、网络等)
  • 优化GameMaker项目性能
  • 任何GameMaker Studio 2开发任务

Official GameMaker Manual

GameMaker官方手册

PRIMARY REFERENCE: Always consult the official GameMaker Manual for comprehensive, up-to-date documentation: https://manual.gamemaker.io/monthly/en/
主要参考资料:如需全面、最新的文档,请始终查阅GameMaker官方手册: https://manual.gamemaker.io/monthly/en/

Key Manual Sections

手册核心章节

When to use the official manual:
  • Looking up function signatures and parameters
  • Understanding platform-specific behavior
  • Checking latest syntax changes for your IDE version
  • Detailed explanations of GameMaker features
何时使用官方手册:
  • 查阅函数签名与参数
  • 了解平台专属行为
  • 检查对应IDE版本的最新语法变更
  • 获取GameMaker功能的详细说明

Additional References

额外参考资料

For advanced architectural guidance:
  • Architecture Patterns: references/ARCHITECTURE_PATTERNS.md
    • GameMaker-specific patterns (Service Locator, Command Pattern, Event-Driven Flow)
    • SOLID principles adapted for GML
    • Encapsulation patterns with manager constructors
    • Performance patterns and anti-patterns
  • Manager Constructor Guide: references/MANAGER_CONSTRUCTOR_GUIDE.md
    • Step-by-step guide for creating manager constructors
    • Public API design patterns
    • Reference exposure pattern for backwards compatibility
    • Cleanup responsibilities and testing strategies
  • Built-in Variables: references/BUILT_IN_VARIABLES.md
    • Complete list of GameMaker reserved variables
    • Position, sprites, physics, paths, timelines categories
    • Deprecated globals (
      health
      ,
      score
      ,
      lives
      )
    • Safe alternatives and validation checklist
  • GML Reference: references/GML_REFERENCE.md
    • Language syntax, operators, data types
  • Common Pitfalls: references/COMMON_PITFALLS.md
    • Frequent mistakes and solutions
  • Quick Reference: references/QUICK_REFERENCE.md
    • Cheat sheet for common patterns
When to use these references:
  • Designing manager constructors for game-wide state
  • Avoiding conflicts with GameMaker built-in variables
  • Implementing encapsulation patterns in GML
  • Understanding
    __
    prefix convention for pseudo-private members
  • Learning SOLID principles in GameMaker context
  • Finding architectural patterns for maintainable code
进阶架构指导:
  • 架构模式references/ARCHITECTURE_PATTERNS.md
    • GameMaker专属模式(服务定位器、命令模式、事件驱动流)
    • 适配GML的SOLID原则
    • 基于管理器构造函数的封装模式
    • 性能优化模式与反模式
  • 管理器构造函数指南references/MANAGER_CONSTRUCTOR_GUIDE.md
    • 创建管理器构造函数的分步指南
    • 公共API设计模式
    • 用于向后兼容的引用暴露模式
    • 清理职责与测试策略
  • 内置变量references/BUILT_IN_VARIABLES.md
    • GameMaker保留变量完整列表
    • 位置、精灵、物理、路径、时间线分类
    • 已弃用全局变量(
      health
      score
      lives
    • 安全替代方案与验证清单
  • GML参考references/GML_REFERENCE.md
    • 语言语法、运算符、数据类型
  • 常见陷阱references/COMMON_PITFALLS.md
    • 常见错误与解决方案
  • 速查手册references/QUICK_REFERENCE.md
    • 常见模式速查表
何时使用这些参考资料:
  • 设计游戏全局状态的管理器构造函数
  • 避免与GameMaker内置变量冲突
  • 在GML中实现封装模式
  • 理解伪私有成员的
    __
    前缀约定
  • 在GameMaker语境下学习SOLID原则
  • 寻找可维护代码的架构模式

Core GameMaker Workflows

GameMaker核心工作流程

Object Creation Workflow (CRITICAL)

对象创建流程(至关重要)

Creating GameMaker objects requires completing ALL four steps. Missing any step will cause the object to not appear in the IDE or fail to compile.
创建GameMaker对象需完成以下全部四个步骤。遗漏任何一步都会导致对象无法在IDE中显示或编译失败。

Step 1: Create Object Directory

步骤1:创建对象目录

bash
objects/objYourObjectName/
Naming Convention:
  • Start with
    obj
    prefix
  • Use PascalCase (e.g.,
    objPlayer
    ,
    objEnemyMelee
    ,
    objInventoryUI
    )
  • Descriptive name indicating purpose
bash
objects/objYourObjectName/
命名规范:
  • obj
    前缀开头
  • 使用帕斯卡命名法(例如:
    objPlayer
    objEnemyMelee
    objInventoryUI
  • 名称需能清晰表明对象用途

Step 2: Create Event Files

步骤2:创建事件文件

Create
.gml
files for each event your object needs:
Common Events:
Event FileEvent TypeWhen to Use
Create_0.gml
Create EventInitialize variables (ALWAYS include)
Step_0.gml
Step EventUpdate logic every frame
Draw_0.gml
Draw EventRender in-world graphics
Draw_64.gml
Draw GUI EventRender UI overlays
Destroy_0.gml
Destroy EventCleanup when destroyed
Collision_objX.gml
Collision EventHandle collisions
Event Naming Rules:
  • Create:
    Create_0.gml
  • Step:
    Step_0.gml
  • Draw:
    Draw_0.gml
  • Draw GUI:
    Draw_64.gml
    (NOT
    Draw_GUI_0.gml
    !)
  • Collision:
    Collision_objTargetName.gml
Example Create_0.gml:
gml
/// objPlayer Create Event
// Initialize player variables

// Movement
move_speed = 4;
direction = 0;

// Stats
health = 100;
max_health = 100;

// State
is_moving = false;

show_debug_message("objPlayer created");
为对象所需的每个事件创建
.gml
文件:
常见事件:
事件文件事件类型适用场景
Create_0.gml
创建事件初始化变量(必须包含)
Step_0.gml
步事件每帧更新逻辑
Draw_0.gml
绘制事件渲染游戏世界图形
Draw_64.gml
GUI绘制事件渲染UI叠加层
Destroy_0.gml
销毁事件对象销毁时执行清理操作
Collision_objX.gml
碰撞事件处理碰撞逻辑
事件命名规则:
  • 创建事件:
    Create_0.gml
  • 步事件:
    Step_0.gml
  • 绘制事件:
    Draw_0.gml
  • GUI绘制事件:
    Draw_64.gml
    (注意:不是
    Draw_GUI_0.gml
    !)
  • 碰撞事件:
    Collision_objTargetName.gml
示例Create_0.gml:
gml
/// objPlayer 创建事件
// 初始化玩家变量

// 移动相关
move_speed = 4;
direction = 0;

// 属性
health = 100;
max_health = 100;

// 状态
is_moving = false;

show_debug_message("objPlayer created");

Step 3: Create .yy File (REQUIRED)

步骤3:创建.yy文件(必填)

File:
objects/objYourObjectName/objYourObjectName.yy
Template:
json
{
  "$GMObject":"",
  "%Name":"objYourObjectName",
  "eventList":[
    {"$GMEvent":"v1","%Name":"","collisionObjectId":null,"eventNum":0,"eventType":0,"isDnD":false,"name":"","resourceType":"GMEvent","resourceVersion":"2.0",},
    {"$GMEvent":"v1","%Name":"","collisionObjectId":null,"eventNum":64,"eventType":8,"isDnD":false,"name":"","resourceType":"GMEvent","resourceVersion":"2.0",},
    {"$GMEvent":"v1","%Name":"","collisionObjectId":null,"eventNum":0,"eventType":3,"isDnD":false,"name":"","resourceType":"GMEvent","resourceVersion":"2.0",},
  ],
  "managed":true,
  "name":"objYourObjectName",
  "overriddenProperties":[],
  "parent":{
    "name":"Objects",
    "path":"folders/Objects.yy",
  },
  "parentObjectId":null,
  "persistent":false,
  "physicsAngularDamping":0.1,
  "physicsDensity":0.5,
  "physicsFriction":0.2,
  "physicsGroup":1,
  "physicsKinematic":false,
  "physicsLinearDamping":0.1,
  "physicsObject":false,
  "physicsRestitution":0.1,
  "physicsSensor":false,
  "physicsShape":1,
  "physicsShapePoints":[],
  "physicsStartAwake":true,
  "properties":[],
  "resourceType":"GMObject",
  "resourceVersion":"2.0",
  "solid":false,
  "spriteId":null,
  "spriteMaskId":null,
  "visible":true,
}
Event Type Numbers:
EventeventTypeeventNum
Create00
Step30
Draw80
Draw GUI864
Destroy10
Important Fields:
  • %Name
    and
    name
    : Must match object name exactly
  • eventList
    : Include entry for each .gml file created
  • parentObjectId
    : Set to parent object resource path if using inheritance (e.g.,
    {"name":"objCreature","path":"objects/objCreature/objCreature.yy"}
    )
  • persistent
    : Set to
    true
    if object should persist across rooms
  • visible
    : Set to
    false
    for controller objects with no sprite
文件路径
objects/objYourObjectName/objYourObjectName.yy
模板:
json
{
  "$GMObject":"",
  "%Name":"objYourObjectName",
  "eventList":[
    {"$GMEvent":"v1","%Name":"","collisionObjectId":null,"eventNum":0,"eventType":0,"isDnD":false,"name":"","resourceType":"GMEvent","resourceVersion":"2.0",},
    {"$GMEvent":"v1","%Name":"","collisionObjectId":null,"eventNum":64,"eventType":8,"isDnD":false,"name":"","resourceType":"GMEvent","resourceVersion":"2.0",},
    {"$GMEvent":"v1","%Name":"","collisionObjectId":null,"eventNum":0,"eventType":3,"isDnD":false,"name":"","resourceType":"GMEvent","resourceVersion":"2.0",},
  ],
  "managed":true,
  "name":"objYourObjectName",
  "overriddenProperties":[],
  "parent":{
    "name":"Objects",
    "path":"folders/Objects.yy",
  },
  "parentObjectId":null,
  "persistent":false,
  "physicsAngularDamping":0.1,
  "physicsDensity":0.5,
  "physicsFriction":0.2,
  "physicsGroup":1,
  "physicsKinematic":false,
  "physicsLinearDamping":0.1,
  "physicsObject":false,
  "physicsRestitution":0.1,
  "physicsSensor":false,
  "physicsShape":1,
  "physicsShapePoints":[],
  "physicsStartAwake":true,
  "properties":[],
  "resourceType":"GMObject",
  "resourceVersion":"2.0",
  "solid":false,
  "spriteId":null,
  "spriteMaskId":null,
  "visible":true,
}
事件类型编号:
事件eventTypeeventNum
创建事件00
步事件30
绘制事件80
GUI绘制事件864
销毁事件10
重要字段:
  • %Name
    name
    :必须与对象名称完全一致
  • eventList
    :为每个创建的.gml文件添加对应条目
  • parentObjectId
    :若使用继承,设置为父对象资源路径(例如:
    {"name":"objCreature","path":"objects/objCreature/objCreature.yy"}
  • persistent
    :若对象需跨房间持久存在,设置为
    true
  • visible
    :对于无精灵的控制器对象,设置为
    false

Step 4: Register in Project File (REQUIRED)

步骤4:在项目文件中注册(必填)

File:
YourProject.yyp
Location: Find the
"resources":[
array
Add Entry (alphabetically sorted):
json
{"id":{"name":"objYourObjectName","path":"objects/objYourObjectName/objYourObjectName.yy",},},
Example:
json
"resources":[
  {"id":{"name":"objInventoryUI","path":"objects/objInventoryUI/objInventoryUI.yy",},},
  {"id":{"name":"objPlayer","path":"objects/objPlayer/objPlayer.yy",},},
  {"id":{"name":"objYourObjectName","path":"objects/objYourObjectName/objYourObjectName.yy",},},
]
CRITICAL: Missing this step will cause compile errors like "object not found".
文件路径
YourProject.yyp
位置:找到
"resources":[
数组
添加条目(按字母顺序排序):
json
{"id":{"name":"objYourObjectName","path":"objects/objYourObjectName/objYourObjectName.yy",},},
示例:
json
"resources":[
  {"id":{"name":"objInventoryUI","path":"objects/objInventoryUI/objInventoryUI.yy",},},
  {"id":{"name":"objPlayer","path":"objects/objPlayer/objPlayer.yy",},},
  {"id":{"name":"objYourObjectName","path":"objects/objYourObjectName/objYourObjectName.yy",},},
]
至关重要:遗漏此步骤会导致“对象未找到”等编译错误。

GML Language Essentials

GML语言基础

Variable Scope

变量作用域

gml
// Local variable (function/script scope only)
var _local_var = 100;

// Instance variable (attached to object instance)
instance_var = 50;

// Global variable (accessible everywhere)
global.game_state = "playing";
Best Practice: Start local variable names with underscore
_
for clarity.
gml
// 局部变量(仅在函数/脚本作用域内有效)
var _local_var = 100;

// 实例变量(绑定到对象实例)
instance_var = 50;

// 全局变量(可在任意位置访问)
global.game_state = "playing";
最佳实践:局部变量名称以下划线
_
开头,以提升可读性。

Data Types

数据类型

  • Real: Numbers
    var _x = 100;
    var _pi = 3.14159;
  • String: Text
    var _name = "Player";
  • Boolean: True/False
    var _is_alive = true;
  • Array:
    var _items = [1, 2, 3];
    var _nested = [[1,2], [3,4]];
  • Struct:
    var _player = { x: 0, y: 0, health: 100 };
  • Undefined:
    undefined
    (check with
    is_undefined()
    )
  • Pointer/ID: References to instances, data structures, assets
  • 实数:数字
    var _x = 100;
    var _pi = 3.14159;
  • 字符串:文本
    var _name = "Player";
  • 布尔值:真/假
    var _is_alive = true;
  • 数组
    var _items = [1, 2, 3];
    var _nested = [[1,2], [3,4]];
  • 结构体
    var _player = { x: 0, y: 0, health: 100 };
  • 未定义
    undefined
    (使用
    is_undefined()
    检测)
  • 指针/ID:指向实例、数据结构、资源的引用

Operators

运算符

Arithmetic:
+ - * / div mod
Comparison:
== != > < >= <=
Logical:
&& || ! ^^ (and, or, not, xor)
Bitwise:
& | ^ << >> ~
Ternary:
condition ? true_value : false_value
CRITICAL - Ternary Operator Chaining:
Chained ternary operators MUST wrap nested conditions in double parentheses:
gml
// ✅ CORRECT
var _result = condition_a ? "foo" : ((condition_b ? "bar" : "baz"));

// ❌ WRONG (will cause compile error in some versions)
var _result = condition_a ? "foo" : condition_b ? "bar" : "baz";
算术运算符
+ - * / div mod
比较运算符
== != > < >= <=
逻辑运算符
&& || ! ^^ (and, or, not, xor)
位运算符
& | ^ << >> ~
三元运算符
condition ? true_value : false_value
至关重要 - 三元运算符链式调用:
链式调用三元运算符必须将嵌套条件用双层括号包裹:
gml
// ✅ 正确写法
var _result = condition_a ? "foo" : ((condition_b ? "bar" : "baz"));

// ❌ 错误写法(部分版本会导致编译错误)
var _result = condition_a ? "foo" : condition_b ? "bar" : "baz";

Control Flow

控制流

gml
// If statement
if (condition) {
    // code
} else if (other_condition) {
    // code
} else {
    // code
}

// Switch statement
switch (value) {
    case 1:
        // code
        break;
    case 2:
    case 3:
        // code for 2 or 3
        break;
    default:
        // code
        break;
}

// For loop
for (var _i = 0; _i < 10; _i++) {
    show_debug_message(_i);
}

// While loop
while (condition) {
    // code
}

// Repeat loop
repeat (10) {
    // code
}

// With loop (iterate instances)
with (objEnemy) {
    health -= 10;
}
gml
// 条件语句
if (condition) {
    // 代码
} else if (other_condition) {
    // 代码
} else {
    // 代码
}

// 分支语句
switch (value) {
    case 1:
        // 代码
        break;
    case 2:
    case 3:
        // 适用于2或3的代码
        break;
    default:
        // 代码
        break;
}

// for循环
for (var _i = 0; _i < 10; _i++) {
    show_debug_message(_i);
}

// while循环
while (condition) {
    // 代码
}

// repeat循环
repeat (10) {
    // 代码
}

// with循环(遍历实例)
with (objEnemy) {
    health -= 10;
}

Data Structures & Memory Management

数据结构与内存管理

Structs (Lightweight - Recommended)

结构体(轻量级 - 推荐使用)

gml
// Create struct (no manual cleanup needed!)
var _player = {
    name: "Hero",
    health: 100,
    max_health: 100,
    level: 1
};

// Access properties
show_debug_message(_player.name); // "Hero"
_player.health -= 10;

// Check if property exists
if (variable_struct_exists(_player, "mana")) {
    // property exists
}

// Dynamic property access
var _prop_name = "health";
var _value = _player[$ _prop_name]; // Same as _player.health
When to use: Lightweight data containers, configuration data, simple key-value pairs. Benefits: No manual cleanup required, garbage collected automatically.
gml
// 创建结构体(无需手动清理!)
var _player = {
    name: "Hero",
    health: 100,
    max_health: 100,
    level: 1
};

// 访问属性
show_debug_message(_player.name); // "Hero"
_player.health -= 10;

// 检查属性是否存在
if (variable_struct_exists(_player, "mana")) {
    // 属性存在
}

// 动态访问属性
var _prop_name = "health";
var _value = _player[$ _prop_name]; // 与_player.health等价
适用场景:轻量级数据容器、配置数据、简单键值对。 优势:无需手动清理,由垃圾回收机制自动处理。

ds_list (Dynamic Array)

ds_list(动态数组)

gml
// Create
var _list = ds_list_create();

// Add items
ds_list_add(_list, "apple", "banana", "cherry");
ds_list_insert(_list, 1, "orange"); // Insert at index

// Access
var _item = _list[| 0]; // "apple"
var _size = ds_list_size(_list);

// Iterate
for (var _i = 0; _i < ds_list_size(_list); _i++) {
    show_debug_message(_list[| _i]);
}

// CRITICAL: Always destroy when done!
ds_list_destroy(_list);
When to use: Large collections, need specific list operations, performance-critical code. CRITICAL: Must manually destroy with
ds_list_destroy()
or memory leak will occur!
gml
// 创建
var _list = ds_list_create();

// 添加元素
ds_list_add(_list, "apple", "banana", "cherry");
ds_list_insert(_list, 1, "orange"); // 在指定索引插入

// 访问元素
var _item = _list[| 0]; // "apple"
var _size = ds_list_size(_list);

// 遍历
for (var _i = 0; _i < ds_list_size(_list); _i++) {
    show_debug_message(_list[| _i]);
}

// 至关重要:使用完毕后必须销毁!
ds_list_destroy(_list);
适用场景:大型集合、需要特定列表操作、性能敏感代码。 至关重要:必须使用
ds_list_destroy()
手动销毁,否则会导致内存泄漏!

ds_map (Key-Value Pairs)

ds_map(键值对)

gml
// Create
var _map = ds_map_create();

// Add items
_map[? "name"] = "Player";
_map[? "health"] = 100;

// Access
var _hp = _map[? "health"]; // 100

// Check if key exists
if (ds_map_exists(_map, "mana")) {
    // key exists
}

// Iterate
var _key = ds_map_find_first(_map);
while (!is_undefined(_key)) {
    show_debug_message(_key + ": " + string(_map[? _key]));
    _key = ds_map_find_next(_map, _key);
}

// CRITICAL: Always destroy when done!
ds_map_destroy(_map);
When to use: Legacy code, need specific map operations, integration with existing ds_map code. CRITICAL: Must manually destroy with
ds_map_destroy()
or memory leak will occur!
Recommendation: Use structs instead of ds_map when possible - they're simpler and don't require manual cleanup.
gml
// 创建
var _map = ds_map_create();

// 添加元素
_map[? "name"] = "Player";
_map[? "health"] = 100;

// 访问元素
var _hp = _map[? "health"]; // 100

// 检查键是否存在
if (ds_map_exists(_map, "mana")) {
    // 键存在
}

// 遍历
var _key = ds_map_find_first(_map);
while (!is_undefined(_key)) {
    show_debug_message(_key + ": " + string(_map[? _key]));
    _key = ds_map_find_next(_map, _key);
}

// 至关重要:使用完毕后必须销毁!
ds_map_destroy(_map);
适用场景:遗留代码、需要特定映射操作、与现有ds_map代码集成。 至关重要:必须使用
ds_map_destroy()
手动销毁,否则会导致内存泄漏!
推荐:尽可能使用结构体替代ds_map,结构体更简单且无需手动清理。

Memory Leak Prevention

内存泄漏预防

Data structures that MUST be destroyed:
  • ds_list_destroy(_list)
  • ds_map_destroy(_map)
  • ds_grid_destroy(_grid)
  • ds_priority_destroy(_priority)
  • ds_queue_destroy(_queue)
  • ds_stack_destroy(_stack)
  • surface_free(_surface)
  • buffer_delete(_buffer)
Pattern for cleanup in Destroy event:
gml
/// objPlayer Destroy Event
// Clean up data structures

if (ds_exists(inventory_list, ds_type_list)) {
    ds_list_destroy(inventory_list);
}

if (surface_exists(shadow_surface)) {
    surface_free(shadow_surface);
}
必须销毁的数据结构:
  • ds_list_destroy(_list)
  • ds_map_destroy(_map)
  • ds_grid_destroy(_grid)
  • ds_priority_destroy(_priority)
  • ds_queue_destroy(_queue)
  • ds_stack_destroy(_stack)
  • surface_free(_surface)
  • buffer_delete(_buffer)
销毁事件中的清理模式:
gml
/// objPlayer 销毁事件
// 清理数据结构

if (ds_exists(inventory_list, ds_type_list)) {
    ds_list_destroy(inventory_list);
}

if (surface_exists(shadow_surface)) {
    surface_free(shadow_surface);
}

File System & Persistence

文件系统与数据持久化

datafiles/ Folder (Included Files)

datafiles/目录(包含的文件)

CRITICAL LIMITATION: Some GameMaker versions only support root-level files in
datafiles/
- NO subdirectories!
✅ CORRECT:
datafiles/config.json
datafiles/items.json
datafiles/level_data.json

❌ WRONG (may not work in all versions):
datafiles/configs/game_config.json
datafiles/data/items/weapons.json
Registration Required: Every file in
datafiles/
must be registered in the
.yyp
project file:
json
{"$GMIncludedFile":"","%Name":"config.json","CopyToMask":-1,"filePath":"datafiles","name":"config.json","resourceType":"GMIncludedFile","resourceVersion":"2.0",},
至关重要的限制:部分GameMaker版本仅支持
datafiles/
根目录下的文件,不支持子目录!
✅ 正确写法:
datafiles/config.json
datafiles/items.json
datafiles/level_data.json

❌ 错误写法(部分版本可能无法正常工作):
datafiles/configs/game_config.json
datafiles/data/items/weapons.json
必须注册
datafiles/
中的每个文件都必须在
.yyp
项目文件中注册:
json
{"$GMIncludedFile":"","%Name":"config.json","CopyToMask":-1,"filePath":"datafiles","name":"config.json","resourceType":"GMIncludedFile","resourceVersion":"2.0",},

JSON Files

JSON文件

gml
// Load JSON from datafiles/
function load_json_file(_filename) {
    if (!file_exists(_filename)) {
        show_debug_message("ERROR: File not found: " + _filename);
        return noone;
    }

    var _file = file_text_open_read(_filename);
    var _json_string = "";
    while (!file_text_eof(_file)) {
        _json_string += file_text_read_string(_file);
        file_text_readln(_file);
    }
    file_text_close(_file);

    return json_parse(_json_string);
}

// Save JSON to working directory
function save_json_file(_filename, _data) {
    var _json_string = json_stringify(_data);
    var _file = file_text_open_write(_filename);
    file_text_write_string(_file, _json_string);
    file_text_close(_file);
}
gml
// 从datafiles/加载JSON
function load_json_file(_filename) {
    if (!file_exists(_filename)) {
        show_debug_message("错误:未找到文件:" + _filename);
        return noone;
    }

    var _file = file_text_open_read(_filename);
    var _json_string = "";
    while (!file_text_eof(_file)) {
        _json_string += file_text_read_string(_file);
        file_text_readln(_file);
    }
    file_text_close(_file);

    return json_parse(_json_string);
}

// 将JSON保存到工作目录
function save_json_file(_filename, _data) {
    var _json_string = json_stringify(_data);
    var _file = file_text_open_write(_filename);
    file_text_write_string(_file, _json_string);
    file_text_close(_file);
}

Save File Locations

存档文件位置

gml
// Working directory (platform-dependent save location)
var _save_path = working_directory + "savegame.json";

// Game save ID (unique folder for your game)
// On Windows: %LOCALAPPDATA%/[game_save_id]/
var _save_id = game_save_id;
gml
// 工作目录(与平台相关的存档位置)
var _save_path = working_directory + "savegame.json";

// 游戏存档ID(游戏专属目录)
// Windows系统:%LOCALAPPDATA%/[game_save_id]/
var _save_id = game_save_id;

Event System & Execution Order

事件系统与执行顺序

Event Execution Order (Per Frame)

每帧事件执行顺序

  1. Begin Step - Before main logic
  2. Alarm Events - Countdown timers
  3. Keyboard/Mouse Events - Input detection
  4. Step - Main update logic
  5. Collision Events - After movement
  6. End Step - After all logic
  7. Draw - Render in-world graphics
  8. Draw GUI - Render UI overlays
  9. Draw End - Post-processing
  1. Begin Step - 主逻辑执行前
  2. Alarm Events - 倒计时计时器
  3. Keyboard/Mouse Events - 输入检测
  4. Step - 主更新逻辑
  5. Collision Events - 移动完成后
  6. End Step - 所有逻辑执行后
  7. Draw - 渲染游戏世界图形
  8. Draw GUI - 渲染UI叠加层
  9. Draw End - 后期处理

Persistent Objects

持久化对象

Set
persistent: true
in
.yy
file to survive room transitions.
CRITICAL: When using persistent objects with event handlers, clear handlers when re-entering rooms to avoid duplicate registrations!
gml
// rmGameplay Room Creation Code
// Clear handlers to prevent duplicates
global.input_controller.clear_all_handlers();

// Register handlers fresh
global.input_controller.register_handler("ACTION", function(_cmd) {
    // handle action
});
.yy
文件中设置
persistent: true
,可让对象在房间切换时保留。
至关重要:当使用带有事件处理器的持久化对象时,重新进入房间时需清除处理器,避免重复注册!
gml
// rmGameplay房间创建代码
// 清除处理器以避免重复注册
global.input_controller.clear_all_handlers();

// 重新注册处理器
global.input_controller.register_handler("ACTION", function(_cmd) {
    // 处理操作
});

Drawing & Graphics

绘图与图形

Basic Drawing

基础绘图

gml
// Draw sprite
draw_sprite(spr_player, image_index, x, y);
draw_sprite_ext(spr_player, image_index, x, y, scale_x, scale_y, rotation, color, alpha);

// Draw text
draw_text(x, y, "Hello World");
draw_set_font(fnt_arial);
draw_set_color(c_white);
draw_set_halign(fa_center);
draw_set_valign(fa_middle);

// Draw shapes
draw_rectangle(x1, y1, x2, y2, outline);
draw_circle(x, y, radius, outline);
draw_line(x1, y1, x2, y2);
gml
// 绘制精灵
draw_sprite(spr_player, image_index, x, y);
draw_sprite_ext(spr_player, image_index, x, y, scale_x, scale_y, rotation, color, alpha);

// 绘制文本
draw_text(x, y, "Hello World");
draw_set_font(fnt_arial);
draw_set_color(c_white);
draw_set_halign(fa_center);
draw_set_valign(fa_middle);

// 绘制形状
draw_rectangle(x1, y1, x2, y2, outline);
draw_circle(x, y, radius, outline);
draw_line(x1, y1, x2, y2);

Surfaces (Render Targets)

表面(渲染目标)

gml
// Create surface
if (!surface_exists(shadow_surface)) {
    shadow_surface = surface_create(room_width, room_height);
}

// Draw to surface
surface_set_target(shadow_surface);
draw_clear_alpha(c_black, 0);
// ... draw operations ...
surface_reset_target();

// Draw surface to screen
draw_surface(shadow_surface, 0, 0);

// CRITICAL: Free surface when done
if (surface_exists(shadow_surface)) {
    surface_free(shadow_surface);
}
gml
// 创建表面
if (!surface_exists(shadow_surface)) {
    shadow_surface = surface_create(room_width, room_height);
}

// 绘制到表面
surface_set_target(shadow_surface);
draw_clear_alpha(c_black, 0);
// ... 绘制操作 ...
surface_reset_target();

// 将表面绘制到屏幕
draw_surface(shadow_surface, 0, 0);

// 至关重要:使用完毕后释放表面
if (surface_exists(shadow_surface)) {
    surface_free(shadow_surface);
}

Performance Optimization

性能优化

Draw Call Optimization

绘制调用优化

  • Minimize draw calls by batching sprites onto texture pages
  • Use layers for static content (backgrounds, tiles)
  • Cache expensive calculations (don't recalculate in Draw event)
  • Avoid creating/destroying instances in Draw events
  • 通过将精灵批量打包到纹理页来减少绘制调用
  • 为静态内容(背景、瓦片)使用图层
  • 缓存昂贵的计算结果(不要在绘制事件中重复计算)
  • 避免在绘制事件中创建/销毁实例

Collision Optimization

碰撞检测优化

  • Use broad-phase distance checks before precise collision
  • Set appropriate collision masks (precise vs bounding box)
  • Use collision layers and groups
  • Consider using
    instance_position()
    instead of
    place_meeting()
    when you need the instance
  • 在精确碰撞检测前使用粗粒度距离检查
  • 设置合适的碰撞掩码(精确碰撞 vs 边界框碰撞)
  • 使用碰撞图层与分组
  • 当需要获取实例时,考虑使用
    instance_position()
    替代
    place_meeting()

Memory Management

内存管理

  • Always destroy data structures when done
  • Free surfaces when no longer needed
  • Delete buffers after use
  • Clean up in Destroy events
  • 使用完毕后始终销毁数据结构
  • 不再需要时释放表面
  • 使用后删除缓冲区
  • 在销毁事件中执行清理操作

Common Pitfalls & Solutions

常见陷阱与解决方案

See COMMON_PITFALLS.md for comprehensive troubleshooting guide.
详细故障排除指南请查阅COMMON_PITFALLS.md

Quick Reference

速查指南

Object Creation Issues:
  • Missing .yy file → Object doesn't appear in IDE → Create .yy file using template above
  • Missing .yyp registration → Compile error "object not found" → Add entry to .yyp resources array
  • Wrong event name → Event doesn't trigger → Use exact names (Draw_64.gml, NOT Draw_GUI_0.gml)
Memory Issues:
  • Data structure leaks → Memory usage grows → Always call ds_destroy functions
  • Surface leaks → Memory usage grows → Always call surface_free()
  • Forgotten Destroy event → Resources not cleaned up → Add Destroy event with cleanup code
File System Issues:
  • datafiles/ subdirectory → File not found error → Move files to datafiles/ root level
  • Missing .yyp registration → Included file not found → Register file in .yyp
GML Syntax Issues:
  • Ternary chaining → Compile error → Wrap nested conditions in double parentheses
  • Variable scope → Undefined variable → Check local vs instance vs global scope
  • Array bounds → Index out of range → Check array size before accessing
对象创建问题:
  • 缺少.yy文件 → 对象未在IDE中显示 → 使用上述模板创建.yy文件
  • 缺少.yyp注册 → 编译错误“对象未找到” → 在.yyp的resources数组中添加条目
  • 事件名称错误 → 事件未触发 → 使用正确的名称(如Draw_64.gml,而非Draw_GUI_0.gml)
内存问题:
  • 数据结构泄漏 → 内存占用持续增长 → 始终调用ds_destroy相关函数
  • 表面泄漏 → 内存占用持续增长 → 始终调用surface_free()
  • 遗漏销毁事件 → 资源未被清理 → 添加包含清理代码的销毁事件
文件系统问题:
  • datafiles/子目录 → 文件未找到错误 → 将文件移至datafiles/根目录
  • 缺少.yyp注册 → 包含的文件未找到 → 在.yyp中注册文件
GML语法问题:
  • 三元运算符链式调用 → 编译错误 → 将嵌套条件用双层括号包裹
  • 变量作用域 → 变量未定义 → 检查局部、实例与全局作用域
  • 数组边界 → 索引越界 → 访问前检查数组大小

Advanced Topics

进阶主题

For in-depth coverage of advanced features, see:
  • GML_REFERENCE.md - Complete GML function reference organized by category
  • QUICK_REFERENCE.md - Tables, constants, and quick lookups
  • ADVANCED_TOPICS.md - Shaders, networking, platform-specific development
如需深入了解进阶功能,请查阅:
  • GML_REFERENCE.md - 按类别划分的完整GML函数参考
  • QUICK_REFERENCE.md - 表格、常量与速查内容
  • ADVANCED_TOPICS.md - 着色器、网络、平台专属开发

Shader Programming (GLSL ES)

着色器编程(GLSL ES)

When to use shaders:
  • Advanced visual effects (lighting, blur, outline, color grading)
  • Per-pixel operations (custom rendering effects)
  • Performance optimization (GPU-based calculations)
Basic shader workflow:
  1. Create shader asset in IDE
  2. Write vertex shader (.vsh) and fragment shader (.fsh)
  3. Set shader:
    shader_set(shd_outline);
  4. Pass uniforms:
    shader_set_uniform_f(u_time, current_time);
  5. Draw sprites/surfaces
  6. Reset shader:
    shader_reset();
See ADVANCED_TOPICS.md for GLSL ES syntax, examples, and common shader patterns.
何时使用着色器:
  • 高级视觉效果(光照、模糊、描边、颜色分级)
  • 逐像素操作(自定义渲染效果)
  • 性能优化(基于GPU的计算)
基础着色器工作流:
  1. 在IDE中创建着色器资源
  2. 编写顶点着色器(.vsh)与片段着色器(.fsh)
  3. 设置着色器:
    shader_set(shd_outline);
  4. 传递 uniforms:
    shader_set_uniform_f(u_time, current_time);
  5. 绘制精灵/表面
  6. 重置着色器:
    shader_reset();
GLSL ES语法、示例与常见着色器模式请查阅ADVANCED_TOPICS.md

Networking & Multiplayer

网络与多人游戏

When to use networking:
  • Multiplayer games (client-server, peer-to-peer)
  • Online leaderboards
  • HTTP API integration
  • Cloud save systems
Async HTTP example:
gml
// Send GET request
var _request_id = http_get("https://api.example.com/data");

// In Async HTTP event
var _id = async_load[? "id"];
if (_id == _request_id) {
    var _status = async_load[? "status"];
    if (_status == 0) {
        var _result = async_load[? "result"];
        var _data = json_parse(_result);
        // Process data
    }
}
See ADVANCED_TOPICS.md for network sockets, buffers, multiplayer architecture, and synchronization patterns.
何时使用网络功能:
  • 多人游戏(客户端-服务器、点对点)
  • 在线排行榜
  • HTTP API集成
  • 云存档系统
异步HTTP请求示例:
gml
// 发送GET请求
var _request_id = http_get("https://api.example.com/data");

// 在异步HTTP事件中
var _id = async_load[? "id"];
if (_id == _request_id) {
    var _status = async_load[? "status"];
    if (_status == 0) {
        var _result = async_load[? "result"];
        var _data = json_parse(_result);
        // 处理数据
    }
}
网络套接字、缓冲区、多人游戏架构与同步模式请查阅ADVANCED_TOPICS.md

Platform-Specific Development

平台专属开发

Mobile (iOS/Android):
  • Touch input:
    device_mouse_x_to_gui()
    ,
    device_mouse_y_to_gui()
  • Virtual buttons:
    virtual_key_add()
  • Sensors:
    device_get_tilt_x()
    ,
    device_get_tilt_y()
Console (PlayStation, Xbox, Nintendo Switch):
  • Gamepad support:
    gamepad_button_check()
    ,
    gamepad_axis_value()
  • Platform detection:
    os_type
    ,
    os_get_config()
HTML5:
  • Browser integration:
    clickable_add()
    ,
    clickable_set_style()
  • JavaScript execution:
    js_runner_eval()
Desktop (Windows, macOS, Linux):
  • File dialogs:
    get_open_filename()
    ,
    get_save_filename()
  • Window control:
    window_set_fullscreen()
    ,
    window_set_size()
See ADVANCED_TOPICS.md for detailed platform-specific development guides.
移动端(iOS/Android):
  • 触摸输入:
    device_mouse_x_to_gui()
    device_mouse_y_to_gui()
  • 虚拟按键:
    virtual_key_add()
  • 传感器:
    device_get_tilt_x()
    device_get_tilt_y()
主机平台(PlayStation、Xbox、Nintendo Switch):
  • 游戏手柄支持:
    gamepad_button_check()
    gamepad_axis_value()
  • 平台检测:
    os_type
    os_get_config()
HTML5:
  • 浏览器集成:
    clickable_add()
    clickable_set_style()
  • JavaScript执行:
    js_runner_eval()
桌面端(Windows、macOS、Linux):
  • 文件对话框:
    get_open_filename()
    get_save_filename()
  • 窗口控制:
    window_set_fullscreen()
    window_set_size()
详细平台专属开发指南请查阅ADVANCED_TOPICS.md

Resources

资源

This skill includes comprehensive reference documentation:
本技能包含全面的参考文档:

references/

references/目录

GML_REFERENCE.md (~1500 lines)
  • Complete GML function reference organized by category
  • Drawing, math, strings, instances, rooms, data structures, files, networking, shaders, surfaces, particles, audio
  • Code patterns for common tasks (inventory, state machines, dialogue, save/load, camera systems)
  • Struct vs Object decision guidance
  • Constructor patterns and method variables
ARCHITECTURE_PATTERNS.md (~500 lines)
  • GameMaker-specific architectural patterns (Service Locator, Command Pattern, Event-Driven Flow, Procedural Logic, Data-Driven Design)
  • Why NOT MVC/MVP for game engines (event-driven vs request/response architecture)
  • SOLID principles in GML context (SRP, OCP, LSP, ISP, DIP with code examples)
  • Design principles (DRY, KISS, YAGNI)
  • Performance patterns (hot path optimization, struct vs ds_map, lookup maps)
  • Anti-patterns to avoid (global abuse, deep hierarchies, function redefinition)
COMMON_PITFALLS.md (~800 lines)
  • Object creation issues (missing .yy, missing .yyp registration, wrong event names)
  • File system issues (datafiles/ subdirectories, .yyp registration, paths)
  • GML syntax traps (ternary operators, variable scope, array bounds, undefined access)
  • Memory management (ds_* leaks, surface leaks, buffer leaks, cleanup patterns)
  • Performance issues (draw optimization, collision optimization, instance management)
  • Networking issues (async events, buffer types, timeouts, platform differences)
  • Shader issues (GLSL ES compatibility, uniform naming, texture sampling)
QUICK_REFERENCE.md (~600 lines)
  • Event type/number complete table with execution order
  • Keyboard constants (vk_* constants, ord() usage, key press vs check)
  • Mouse constants (mb_* constants, mouse event types, device_mouse_* functions)
  • Common GML patterns (distance checks, direction calculation, collision checks, random ranges)
  • Color functions (constants, make_color_, color_get_, merge_color)
  • IDE version reference (common versions, features, compatibility notes)
ADVANCED_TOPICS.md (~1000 lines)
  • Shader Programming (GLSL ES syntax, vertex/fragment shader examples, uniforms, multi-pass techniques, debugging)
  • Networking Patterns (client-server architecture, lobby systems, packet structure, latency compensation, buffers)
  • Platform-Specific Development (mobile touch/sensors, console gamepad/achievements, HTML5 browser API, desktop OS interactions)
  • Advanced Graphics (surfaces, lighting systems, normal maps, particles, tilemaps, cameras)
  • Performance Profiling (debug overlay, bottleneck identification, memory profiling, draw call reduction, code profiling)

Remember: This skill provides guidance and reference. Always consult the official GameMaker Manual for the most up-to-date and comprehensive documentation!
GML_REFERENCE.md(约1500行)
  • 按类别划分的完整GML函数参考
  • 绘图、数学、字符串、实例、房间、数据结构、文件、网络、着色器、表面、粒子、音频
  • 常见任务的代码模式(背包、状态机、对话、存档/读档、相机系统)
  • 结构体与对象的选择指导
  • 构造函数模式与方法变量
ARCHITECTURE_PATTERNS.md(约500行)
  • GameMaker专属架构模式(服务定位器、命令模式、事件驱动流、过程化逻辑、数据驱动设计)
  • 为何游戏引擎不适合MVC/MVP(事件驱动 vs 请求/响应架构)
  • GML语境下的SOLID原则(包含代码示例的单一职责、开闭、里氏替换、接口隔离、依赖倒置原则)
  • 设计原则(DRY、KISS、YAGNI)
  • 性能优化模式(热路径优化、结构体vs ds_map、查找映射)
  • 需要避免的反模式(全局变量滥用、深层继承、函数重定义)
COMMON_PITFALLS.md(约800行)
  • 对象创建问题(缺少.yy文件、缺少.yyp注册、事件名称错误)
  • 文件系统问题(datafiles/子目录、.yyp注册、路径)
  • GML语法陷阱(三元运算符、变量作用域、数组边界、未定义访问)
  • 内存管理(ds_*泄漏、表面泄漏、缓冲区泄漏、清理模式)
  • 性能问题(绘制优化、碰撞检测优化、实例管理)
  • 网络问题(异步事件、缓冲区类型、超时、平台差异)
  • 着色器问题(GLSL ES兼容性、uniform命名、纹理采样)
QUICK_REFERENCE.md(约600行)
  • 包含执行顺序的完整事件类型/编号表
  • 键盘常量(vk_*常量、ord()用法、按键按下vs持续检测)
  • 鼠标常量(mb_常量、鼠标事件类型、device_mouse_函数)
  • 常见GML模式(距离检查、方向计算、碰撞检测、随机范围)
  • 颜色函数(常量、make_color_、color_get_、merge_color)
  • IDE版本参考(常见版本、功能、兼容性说明)
ADVANCED_TOPICS.md(约1000行)
  • 着色器编程(GLSL ES语法、顶点/片段着色器示例、uniform、多通道技术、调试)
  • 网络模式(客户端-服务器架构、大厅系统、数据包结构、延迟补偿、缓冲区)
  • 平台专属开发(移动端触摸/传感器、主机平台游戏手柄/成就、HTML5浏览器API、桌面端系统交互)
  • 高级图形(表面、光照系统、法线贴图、粒子、瓦片地图、相机)
  • 性能分析(调试叠加层、瓶颈识别、内存分析、绘制调用减少、代码分析)

注意:本技能仅提供指导与参考。如需最新、最全面的文档,请始终查阅GameMaker官方手册!