CHUAN2 DEV ENGINE
996 正版授权研发中心 · 360 授权合作教学中心 · 抖音传奇直播合作授权 · 快手推广运营商授权
OFFICIAL LICENSED ACADEMY 查验官方授权证书 →
// 威海旷世互娱教学基地 · 技术文章
进阶实战游戏功能996引擎

空城疑纹:你越不打,它越心虚

2026-10-02 00:24 作者:996 技术组 996引擎Lua教程传奇脚本进阶实战游戏功能996引擎

【游戏功能】

上一版埋了个反着来的隐蔽报错:空城纹的疑心标记没清——玩家挂机挂了十分钟回来,怪的破绽还开着,刀刀重击,一看日志,疑心的清除分支挂在纹的卸载里,纹提前断了标记就成了永久的。修完把清除挪进标记自己的生命周期,顺手把这套机制写成篇。空城纹的账是一出戏:你三门大开、三秒不还手,怪反而心虚——它犯疑的那三秒,爪软一半、破绽大敞。这篇把整改后的整套模块拆开:配置表、空城计时、疑心判定、破绽结算、定时器、调试按钮,一段一段照抄能跑。

一、效果演示:你越不打,它越心虚

演示场怪照常压上来,你偏不还手。点「空城!」:一圈青灰色的纹罩上玩家——十二秒空城期。这一拍起计时的不是怪的出手,是你的忍性:三秒不还手,怪开始犯嘀咕——"疑?"的字从它头顶浮起,破绽当场大敞:它的下一爪软了一半只有七点,出手还慢了半拍;你这三秒里落下去的刀刀刀十五点。你一还手,计时归零重新憋——疑心的三秒一过它回过神,破绽合上,一切照旧。演示里试两笔账:憋三秒疑心期的输出窗口和见刀就砍的平常账——会唱空城的人,三秒的静场换来三秒的敞门。空城纹教的是示弱:最凶的破绽,长在它最犯疑的那一拍。

demo
 fx-emptyfort

二、底层原理:一道空城计时加一次疑心判定

模块的机关是一对搭档。空城计时:纹成期里你的出手每一拍过表——三秒不出手,空城唱成,这是整套纹唯一的输入条件。疑心判定:空城唱成的那一拍怪当场犯疑——疑心三秒,爪软一半、破绽大敞,你的刀趁虚而入。和破防类机制的分野在"空城的破绽是你唱出来的":破甲拆它的防,空城疑它的心——你一动不动,它自己吓自己,这份"不战而屈人之兵"的戏是空城纹的魂。

疑心为什么破绽只有三秒?疑心常开的版本空城变成挂机增伤,三十六计唱成了死城计;三秒的破绽逼着玩家"唱完就打"——空城的戏在你忍的那三秒,破绽的账在你抢的那三秒。

三、核心代码:完整模块(上·骨架)

lua
-- @file EmptyFort.lua
-- 空城疑纹 —— 你越不打,它越心虚

local EmptyFort = {}

local CONST = {
    CREST_LIFE    = 12.0,
    CREST_CD      = 4.0,
    FORT_LIFE     = 3.0,
    DOUBT_LIFE    = 3.0,
    CALM_HIT      = 15,
    BASE_HIT      = 12,

    COLOR_FORT    = "#8898a8",
    COLOR_DEEP    = "#2e3848",
    COLOR_GHOST   = "#c8d8e8",

    ZORDER_FORT   = 133,
    ZORDER_FX     = 135,
    AUTOINC_BASE  = 1131000,
}

local _crestT    = 0
local _cdLeft    = 0
local _idleT     = 0
local _doubtT    = 0
local _crestFx   = nil
local _scheduler = nil
local _autoInc   = 0

local function GenID(prefix)
    _autoInc = _autoInc + 1
    return string.format("%s_%d", prefix or "EMF",
        CONST.AUTOINC_BASE + _autoInc)
end

local function GetActorPos(id)
    if not id then return nil end
    local x = SL:GetValue("ACTOR_POSITION_X", id)
    local y = SL:GetValue("ACTOR_POSITION_Y", id)
    if not x or not y then return nil end
    return { x = x, y = y }
end

local function SafeRemove(node)
    if node and not GUI:Widget_IsNull(node) then
        GUI:removeFromParent(node)
    end
end

local function ShowTip(msg)
    if msg and msg ~= "" then SL:ShowSystemTips(msg) end
end

function EmptyFort.Doubtful()
    return _doubtT > 0
end

四、核心代码:完整模块(下·疑心判定与破绽结算)

lua
-- 破绽结算:疑心期的刀走敞门档
SL:RegisterLUAEvent(LUA_EVENT_MELEE_DAMAGE, "EMF_Open", function()
    if not EmptyFort.Doubtful() then return 0 end
    return CONST.CALM_HIT - CONST.BASE_HIT
end)

-- 疑心标记:自带生命周期,清除不挂在别处
SL:RegisterLUAEvent(LUA_EVENT_BEFORE_HURT, "EMF_Calm", function(dmg)
    if not EmptyFort.Doubtful() then return dmg end
    return math.floor(dmg / 2)
end)

function EmptyFort.Cast()
    if _cdLeft > 0 or _crestT > 0 then return end
    local myID = SL:GetValue("USER_ID")
    _cdLeft = CONST.CREST_CD
    _crestT = CONST.CREST_LIFE
    _idleT = 0
    _doubtT = 0
    SafeRemove(_crestFx)
    _crestFx = GUI:Layout_Create(GUI:Attach_SceneF(),
        GenID("Fort"), 0, 0, 0, 0, false)
    GUI:setLocalZOrder(_crestFx, CONST.ZORDER_FORT)
    SL:PlayFortUpFx(myID)
    ShowTip("城门开了——三秒不还手,它就犯疑")
end

-- 定时器:空城计时、疑心倒计时与标记自清
if not _scheduler then
    _scheduler = SL:Schedule(function(dt)
        _cdLeft = math.max(0, _cdLeft - dt)
        if _crestT > 0 then
            _crestT = _crestT - dt
            if _doubtT > 0 then
                _doubtT = _doubtT - dt
                if _doubtT <= 0 then
                    ShowTip("它回过神了——破绽合上了")
                end
            else
                _idleT = _idleT + dt
                if _idleT >= CONST.FORT_LIFE then
                    _idleT = 0
                    _doubtT = CONST.DOUBT_LIFE
                    SL:PlayDoubtFx(SL:GetValue("MARK_TARGET_ID"))
                    ShowTip("它犯疑了——下一爪软一半,破绽露三秒")
                end
            end
            if _crestT <= 0 then
                _doubtT = 0
                SafeRemove(_crestFx)
                ShowTip("城门关了——疑心散了")
            end
        end
    end, 0.02)
end

SL:ScheduleOnce(function()
    SL:BindDebugButton("空城", function()
        EmptyFort.Cast()
    end)
    ShowTip("技能已加载: 空城纹 (调试按钮触发)")
end, 1.0)

function EmptyFort.Unload()
    if _scheduler then SL:Unschedule(_scheduler) end
    SL:UnregisterLUAEvent(LUA_EVENT_MELEE_DAMAGE, "EMF_Open")
    SL:UnregisterLUAEvent(LUA_EVENT_BEFORE_HURT, "EMF_Calm")
    SafeRemove(_crestFx)
    _crestT = 0
    _doubtT = 0
end

return EmptyFort

五、机制问答

问:还手会打断疑心吗?
答:分两头——疑心没发作前还手,空城计时归零从头憋;疑心发作后还手,三秒的敞门照走不误,打不打它它都敞着。

问:三秒里它没攻击我也算吗?
答:算——空城认的是你没出手,它动不动与戏无关,你忍你的,它疑它的。

问:疑心期的它被队友打也吃敞门吗?
答:吃——破绽挂在它身上不认刀主,队友趁疑心补的刀同样走重档,空城是全队的戏台。

问:连续唱两回空城行吗?
答:行——疑心散了计时重新憋,一门反复开合是老玩家的常规手法,怪疑心一次就长一智的版本谁还敢唱。

问:它出手慢了半拍能看出来吗?
答:能——疑心的爪抬起时带一丝迟疑的停顿,戏做足了玩家才信它真的心虚。

六、调参指南与商业服怎么用

第四笔是标记的自清:疑心标记自带生命周期是那场"永久破绽"报错的正解——清除挂在别人的卸载分支里,主干一断标记就成了孤儿,标记的生老病死要自己管自己。第三笔是空城的门槛:三秒不还手是忍性的定价——门槛太低两刀间隙就唱成,太高一场仗唱不了一回,三秒刚好是"忍得住也唱得响"的线。第二笔是疑心的双账:爪软一半、破绽大敞是疑心的两笔——只软爪不敞门是单纯减伤,只敞门不减爪是纯增伤,双账齐下才有"它自乱阵脚"的戏。第一笔是疑?的浮字:犯疑那一拍"疑?"从它头顶浮起——疑是它的戏,浮字是它的台词,没有台词的空城计唱给谁看。常见坑三个:疑心标记跨场结转的永久破绽;还手归零的判定漏了挥空刀;疑?浮字和受击飘字挤在一处。

商业服里空城纹是"空城派"的独门戏:别人的纹比谁的招狠,他的纹比谁忍得住——商城里空城纹的样式做成品级,柴门纹、吊桥纹、金瓯城纹,那圈罩着玩家的青灰纹就是空城派的城门。运营落地还有两笔:一段是忍戏教学——教一句"手放键盘上,三秒不碰,戏就成了一半",流派第一课是忍;一段是空城榜——按唱成的空城总次数排名,戏唱得最稳的人有碑。变体做成连城:空城唱成期间移动不算破功——从死守到游唱,空城派的城门越唱越活。这一篇的演示和整套模块照抄能跑,改的就是 CONST 那张表。

写完留一句给做示弱系的同学:空城纹卖的是"不战而屈人之兵"——那道三秒一开的城门和它头顶浮起的疑?字,是把玩家的忍性折成敌方破绽的一出戏。

作者履历与出处

本文由 996 技术组基于 996 引擎官方知识库与浮生梦老师课程体系整理。团队长期从事传奇类引擎 Lua 后端逻辑、客户端界面与商业版本交付,内容以官方知识库与真实项目为出处,按版本持续修订。

← 返回文章地图返回研学路径

幂尔框架 · 实战干货 · 接口调用

LATEST ARTICLES

全站技术干货持续更新:996 引擎 / Lua 实战帖,语法、参数与示例一篇讲透。进入文章地图 · 查看全部 →

进阶实战游戏功能

Lua自动炮台:架一个自动索敌开火

【语法算法】 上一版的炮台索敌逻辑有个隐蔽报错:炮台永远打同一个怪——即使那只怪已经死了,索敌的游标也不挪窝。追到底索敌的游…

2026-10-02 04:50 996 技术组
进阶实战游戏功能

Lua元素转换:火伤转冰伤附带减速

【语法算法】 先抛一个坑:打不完的火系怪怎么办?火抗怪火打不动,换冰系技能要切装备要换面板——切完黄花菜都凉了。元素转换的答…

2026-10-02 04:50 996 技术组
进阶实战游戏功能

Lua连锁引燃:一个着火引燃下一个

【语法算法】 上个月的事故复盘会上有个数字被念了三遍:四成——策划写的是"同伴陪疼四成",代码落下去成了"陪疼四十点",两只…

2026-10-02 04:50 996 技术组
进阶实战游戏功能

Lua弹射地垫:踩上去弹飞到空中

【语法算法】 单行代码拆解:弹射初速=-420——弹射的全部动力就这一行的负初速。负号朝上、四百二十是弹射的初速大小——踩上…

2026-10-02 04:50 996 技术组
进阶实战游戏功能

Lua时间减缓:流速减半的局部时差

【语法算法】 上一版的减速类模块全按"乘以零点五"来写,帧率无关的版本照搬了这套写法——结果高帧率机上减速效果好,低帧率机上…

2026-10-02 04:50 996 技术组
进阶实战游戏功能

Lua引力球:丢出去把怪吸过来

【语法算法】 先抛一个坑:怎么把散在四处的怪聚到一起打?逐个拉是笨办法,一个范围技又只能打一片——引力球的答案是一个会动的吸…

2026-10-02 04:50 996 技术组