使用BepInEx;
using GWYF_ModAPI;
[BepInDependency("com.gwyf.modapi.plugin", BepInDependency.DependencyFlags.SoftDependency)]
[BepInPlugin("com.you.mymod", "我的模组", "1.0.0")]
公共类MyMod:BaseUnityPlugin,IMod
{
私有 IModContext _ctx;
公共字符串名称 => “我的模组”;
public string Version => "1.0.0";
public string Author => "你";
公开字符串 描述 => “做很酷的事”;
醒来
{
_ctx = ModManagerAPI.GetOrCreateContext(this);
_ctx.GetHarmony().PatchAll(); // 两种方式都可行
_ctx.Log("已加载!"); // 回退到 BepInEx 日志记录器
}
public void OnLoad(IModContext ctx) { _ctx = ctx; } // 升级为托管模式
public void OnUpdate() { } public void OnGUI() { } public void OnFixedUpdate() { }
public void OnUnload() { } public void OnSceneChanged(string s) { }
}实现中 模组 是可选的——一个普通的 BepInEx 插件仍然可以正常工作;只是在管理器存在时才会获得额外功能。软 前置依赖 让你的模组加载前先加载API。使用BepInEx;
使用GWYF_ModAPI;
使用UnityEngine;
[BepInPlugin("com.gwyf.mainmenutest", "主菜单测试", "1.0.0")]
公共类主菜单插件:基础Unity插件,模组接口
{
公共字符串 Name => "主菜单测试";
public string Version => "1.0.0";
公共字符串 作者 => "你";
在主菜单上绘制一个标签。
private IModContext _ctx;
私有布尔变量 _onMainMenu;
void Awake()
{
_ctx = ModManagerAPI.GetOrCreateContext(this);
_ctx.Log("主菜单测试已加载!");
}
public void OnLoad(IModContext ctx) { _ctx = ctx; _ctx.Log("已升级为托管模式"); }
public void OnGUI()
{
如果不在主菜单,则返回;
GUI.Label(new Rect(20, Screen.height - 40, 400, 30), "主菜单测试正在运行!");
}
public void OnSceneChanged(string scene) { _onMainMenu = scene.Contains("Menu"); }
public void OnUpdate() { }
public void OnFixedUpdate() { }
public void OnUnload() { _ctx?.Log("正在卸载"); }
}开发工具: 设置 > 开发者 > 生成模板 创建一个已配置好 .csproj 的即用项目。若要使用热重载,请将生成的 DLL 放入 gwyf_mods/ (非 BepInEx/plugins)- 重建并 Ctrl+R 不到一秒就能识别更改,无需重启。_ctx.GetHarmony().PatchAll(); // 卸载时自动取消补丁
_ctx.TrackObject(myGameObject); // 卸载时自动销毁
_ctx.StartTrackedCoroutine(MyRoutine()); // 卸载时自动停止
5秒后执行(5秒后记录“5秒后”)
_ctx.OnRoundStart(() => _ctx.Log("回合开始"));
_ctx.OnPlayerJoined(p => _ctx.Log(p.Name + " 加入了"));配置与存档数据。浮点 速度 = _ctx.配置浮点("速度", 1.5f);
_ctx.添加配置滑块("速度", "speed", 0.5f, 5f, 1.5f);
_ctx.SaveData("highscore", "42");
字符串 hs = _ctx.LoadData("highscore", "0");按键绑定(冲突自动解决)。_ctx.BindKey(KeyCode.F8, "切换我的菜单", () => _open = !_open);多人游戏:同步与事件。_ctx.SetSyncedValue("rule", "hardcore"); // 房主设置
string rule = _ctx.GetSyncedValue("rule", "normal"); // 客户端读取
_ctx.OnModEvent("ping", payload => _ctx.Log("收到 " + payload));
_ctx.SendModEvent("ping", "hello");玩家与游戏状态。对 _ctx.GetAllPlayers() 中的每个玩家 p
{_ctx.Log($"{p.Name} ({p.SteamId}) local={p.IsLocal}");}
字符串 阶段 = _ctx.GetGameState(); // "Lobby","Game","Win","Lose"...
_ctx.OnGameStateChanged(s => _ctx.Log("阶段 -> " + s));每游戏钩子。foreach (var name in _ctx.GetCasinoGameTypes()) _ctx.Log(name);
object blackjack = _ctx.FindCasinoGame("二十一点");经济与门票。long money = _ctx.GetBalance();
_ctx.AddBalance(500);
_ctx.RemoveBalance(200); // 余额不足时返回 false主机与游戏控制(仅限主机操作)。 改变比赛结果的判定只对主机生效,在客户端上会返回 false。由于 GWYF 在服务器端解析游戏,主机调用这些判定会决定所有玩家的结果,即使是没有安装模组的玩家也是如此。_ctx.SetBalance(100000); _ctx.SetQuota(50000); _ctx.MeetQuota();
_ctx.AddDayTime(30f); _ctx.FreezeDayTimer(true); _ctx.ProgressDay();
_ctx.SetCurrentFloor(3); _ctx.RemoveAllNPCs(); _ctx.RefreshGroundLoot();
_ctx.SpawnItem(_ctx.GetSpawnableItems()[0], spawnPos);
将升级授予所有单位
_ctx.SetLobbyPrivate(true);
foreach (var p in _ctx.GetAllPlayers()) // 踢出玩家 / 布娃娃玩家 / 传送玩家也一样
if (!p.IsLocal) _ctx.FreezePlayer(p.Transform, true);
// 个人 - 客户端
_ctx.SetMoveSpeedMultiplier(1.5f);_ctx.SetNoClip(true);
_ctx.UnlockAllCosmetics(); _ctx.SetPlayerColor(Color.cyan); _ctx.PlayEmote(0);大厅投票。int id = _ctx.StartVote("跳到下一层?", 0.6f, passed => _ctx.Log(passed ? "通过" : "失败"));
_ctx.CastVote(id, true);
_ctx.OnVoteStarted(v => _ctx.CastVote(v.Id, true));反射与场景搜索。var t = _ctx.FindGameType("MoneyManager");
var all = _ctx.FindAll<MonoBehaviour>();
_ctx.CallMethod(target, "SomeMethod", arg1);
var val = _ctx.GetValue(target, "fieldName");
_ctx.SetValue(target, "fieldName", newValue);UI:主题、窗口和小组件。void OnGUI() {
_rect = _ctx.DrawWindow(9001, "我的模组", _rect, () => {
_tab = _ctx.Tabs(_tab, new[]{"主界面","设置"});
如果 (GUILayout.Button("开始", _ctx.Theme.Button)) { }
});
}
_ctx.RegisterPauseButton("我的模组", () => _open = true);媒体、生成与镜头。var mat = _ctx.CreateMaterial(Color.red, metallic: 0.5f);
_ctx.PlaySound(clip, transform.position);
var go = _ctx.SpawnPrimitive(PrimitiveType.Cube, pos, Vector3.one, mat);
如果 (_ctx.RaycastFromCamera(out var hit, out _, 50f)) { }
{_ctx.SmoothMoveCamera(pos, lookAt)}; {_ctx.RestoreCamera()};实时调试工具包。_ctx.Watch("balance", () => _ctx.GetBalance());
int pin = _ctx.Pin(player, () => player.name, Color.yellow);
_ctx.Mark("已生成Boss", Color.red);
比较跨客户端("rngSeed", () => _seed)模组间服务。_ctx.RegisterService("MyApi", this);
var other = _ctx.GetService<ICoolApi>("OtherModApi");自定义NPC(主机)。int[] guards = _ctx.SpawnNpcWave(5, center, 4f);
对每个卫兵g,执行上下文中的NpcSetColor将g设为红色,并调用NpcMakeAttackable使g可被攻击,攻击力25f。
_ctx.OnNpcSeesPlayer(14f, 90f, (h, player) => _ctx.NpcFollow(h, player));
_ctx.OnNpcDeath(h => _ctx.Log("守卫倒下"));预构建的游戏玩法系统。 现成的背包、制作、货币和升级系统,让模组无需搭建底层框架即可拥有成长体系。每项都会序列化到模组的存档数据中。var bag = new ModInventory { MaxSlots = 24 };
bag.Add("金锭", 3); bag.Remove("金锭", 1);
_ctx.SaveInventory("bag", bag); _ctx.LoadInventory("bag", bag); // 从存档中填充背包
var econ = new CurrencySystem();
econ.Register("gems", "宝石"); // 定义一种货币
econ.Add("", "gems", 100); // "" = 共享所有者(或 steamId)
bool ok = econ.Spend("", "gems", 30); long gems = econ.GetGlobal("gems");
var craft = new CraftingSystem();
craft.Register("potion", "potion").With("herb", 2); // 2 herb -> 1 potion
如果(craft.可制作("potion", bag))craft.制作("potion", bag);
var lvl = new LevelSystem(); lvl.AddXP(250); int level = lvl.Level;
string drop = new WeightedRandom<string>().Add("common", 80).Add("rare", 20).Pick();自定义内容与注册。 注册你自己的内容,以便游戏和其他客户端识别。挑战是数据;物品和槽位模式需要游戏资源。注册挑战(1,“不爆牌”,“在未爆牌的情况下通关一层”,floorIndex: 0,ticketReward: 2);
_ctx.OnChallengeCompleted(ch => _ctx.Log("挑战完成"));
_ctx.RegisterCustomItem(9001, "幸运币", "重掷一次", myPrefab);
_ctx.RegisterSlotPattern(new bool[15], multiplier: 5f);
_ctx.RegisterInteractable(myGameObject, t => Open(), onHover: t => Highlight(t));
_ctx.RegisterSettingsTab("我的模组");
_ctx.RegisterSettingsSlider("我的模组", "vol", "音量", 0f, 1f, 0.8f);网络生成与远程过程调用。 所有客户端可见的对象,外加模组间消息传递——不含 Mirror 代码。_ctx.RegisterNetworkedPrefab(chestPrefab, "mychest");
GameObject chest = _ctx.SpawnNetworked("mychest", pos); // 返回该对象;所有客户端都能看到它
_ctx.DespawnNetworked(chest);
_ctx.RegisterRpc("open", arg => _ctx.Log("已打开 " + arg)); // 处理程序为 Action<string>
_ctx.SendRpc("open", "chest#1");
_ctx.RegisterRequestHandler("getScore", arg => (object)_score);赌场作弊与游戏内部机制(主持人)。 重皮与自定义概率背后的深层机制。由房主控制;服务器权威,因此它决定所有人的回合。_ctx.SetSlotSymbols(mySpriteAtlas); // 用于转轮的精灵数组
_ctx.SetSeed(12345); int seed = _ctx.GetSeed();
_ctx.ApplyGoldenChipToAllGames(2f); // 赢取倍数
_ctx.SetCatchUpFactor(1.5f);
_ctx.ReplaceGameSprite("DiceGame", "diceFace", mySprite);
_ctx.ForceGameState("Win");
_ctx.SetGameField("Blackjack", "dealerTotal", 17);物品、经济与玩家操作。ulong id = _ctx.GetLocalPlayerInfo().SteamId;
_ctx.GiveItem(id, 9001); _ctx.TakePlayerItem(id); _ctx.ThrowPlayerItem(id);
_ctx.SetBetLimits(5f); // 普通上限的5倍;SetBetLimits(1f, removeLimits: true) 可解除上限
长期净胜场 = _ctx.GetLifetimeNet(); // + GetLifetimeWins() / GetLifetimeLosses()
治疗玩家(id);治疗所有玩家();
_ctx.SetPlayerVoiceEffect("PlayerName", VoiceEffect.High);
_ctx.SetOrgan(id, "head", true);HTTP、音乐、确认与世界标签。_ctx.HttpGet(url, res => _ctx.Log(res)); _ctx.HttpPost(url, jsonBody, res => {});
AudioSource music = _ctx.PlayMusic(@"C:\path\song.wav", loop: true); _ctx.StopMusic(music);
_ctx.ShowConfirm("重置本次挑战?", () => _ctx.ResetSave());
int labelId = _ctx.WorldLabel(pos, () => "Boss", Color.red); // text is a Func<string>══════════ 陷阱 ══════════
BepInEx整合包
BepInEx2026-05-03 03:50:12

禁用计时器
CostMillion2026-09-11 15:40:28
禁用计时器是《和朋友赌博》的一个模组,它会移除每日赌场活动中的计时器。正常情况下,你每天只能在赌场里玩5分钟,之后就会被强制传送出去。这个模组会禁用计时器,

r2modman
ebkr2026-05-13 16:19:12
一个简单易用的模组管理器,适用于许多使用Thunderstore的游戏

赌场菜单 - 模组菜单
Yebbs692026-05-08 12:57:43
一个用于《Gamble With Your Friends》的BepInEx模组菜单,具备金钱/票券注入、配额完成、触发胜利、速度修改、游戏速度控制、天数计时器操控等功能

共享升级(仅限主机)
SELCreative2026-05-05 23:24:12
厌倦了看着有升级的朋友赌博吗?将升级书分享给整个房间,并根据玩家数量动态调整配额难度。只需房主安装即可!

俄罗斯轮盘赌 和你的朋友对赌
DimaLooper2026-07-28 20:23:10
纹理俄化

GWYF 预测器
0verFallen2026-06-29 23:17:12
预测GWYF中确定性游戏的结果。献给那些格外倒霉的人。

不停站
SaltedByte2026-05-02 17:42:24
跳过回合间的等待时间:自动跳过数据统计,加快倒计时,不再播放失败过场动画,并增加投票认输按钮。