下载客户端

用于模组制作和地图编辑的高质量快速随机数生成器

AI智能总结导读

本文为模组制作和地图编辑介绍了梅森旋转算法19937(MT19937)随机数生成器,指出Source Engine自带随机数函数存在分布差等问题,而MT19937具备周期长、随机性优等优势,还提供了其在Squirrel语言的实现代码及使用示例,可用于提升模组和地图的随机数质量。

This guide introduces the well-known Mersenne Twister 19937 random number generator to VScripts for Modding. Implemention of MT19937 RNG in Squirrel code is provided. Code is simple and easy to use in your Add-ons / Maps. Introduction Random Number Generators (RNGs) are infrastructure of many games and mods. However, the RandomInt() / RandomFloat() and such provided by Source Engine have their issues: they have bad distribution and potentially have bias on some numbers in the range you specifies. The reason for this is not the topic here. But a brief description is that the engine (probably) uses rand() in <random.h> of C, which is OK for FPS games but not good enough in terms of randomness. What is Mersenne Twister 19937Mersenne Twister 19937 is a widely-used pseudo random number generator (PRNG). It is known for its long period of 2^19937-1, high-quality randomness, and efficiency. MT19937 is implemented in many programming languages, including C++. Unfortunately, the game does not provide such an interface to access MT19937. Therefore, we have to implement it using Squirrel. Advantages of MT19937 Extremely Long Period: A period of 2^19937-1 ensures virtually no repetition in practical applications. High Quality of Randomness: Produces well-distributed random numbers, passing rigorous randomness tests like Diehard and TestU01. Fast and Efficient: Despite its complex algorithm, it is optimized for speed and suitable for performance-critical applications. Cross-Platform Consistency: Generates consistent results across platforms when initialized with the same seed. Flexibility: Supports integration with various probability distributions (e.g., uniform, normal). Implementing MT19937 in Your Add-on / Map VScript You can put the following code in your *.nut file. it works fine in global scope. Note: DO NOT use variables and functions starting with a '_'. Source Code/*------------------------- // High-quality random number generator based on Mersenne Twister 19937 (MT19937) algorithm, // supporting unbiased uniform and normal distributions. // For Squirrel Vscripts of Source Engine games --------------------------*/ //Global variables used by MT19937. DO NOT touch these two variables _mtArray <- array(624); // State array _mtIndex <- 0; /*------------------------- //Followings are all global functions. DO NOT call functions starting with a '_'. --------------------------*/ //Initialize MT19937 engine with the seed. Seed should be an integer. //If you feed MT19937 with the same seed, you will get the same sequence of numbers. //It is advised to call this function only once in your vscpript function RngSetSeed(seed) { _mtArray[0] = seed; for (local i = 1; i < 624; i++) { _mtArray[ i ] = (0x6c078965 * (_mtArray[ i - 1 ] ^ (_mtArray[ i - 1 ] >>> 30)) + i) & 0xffffffff; } _mtIndex = 624; } // Extracts a random number function _RngExtractNumber() { if (_mtIndex >= 624) { _RngTwist(); // Perform a twist operation when index is greater than 624 } local y = _mtArray[_mtIndex++]; y = y ^ (y >>> 11); y = y ^ ((y << 7) & 0x9d2c5680); y = y ^ ((y << 15) & 0xefc60000); y = y ^ (y >>> 18); return y & 0xffffffff; } // Twists the state array to generate new random numbers function _RngTwist() { for (local i = 0; i < 624; i++) { local y = (_mtArray[ i ] & 0x80000000) + (_mtArray[(i + 1) % 624] & 0x7fffffff); _mtArray[ i ] = _mtArray[(i + 397) % 624] ^ (y >>> 1); if (y % 2 != 0) { _mtArray[ i ] = _mtArray[ i ] ^ 0x9908b0df; } } _mtIndex = 0; } // Discards the sign bit to produce a random integer in [0, 0x7fffffff] function _RngRandom() { return _RngExtractNumber() & 0x7fffffff; } // Returns a uniformly distributed random integer in the range [min, max] function RandIntUniformDistribution(min, max) { local range = max - min + 1; local num; // Set the upper limit of random range local securemax = (0x7fffffff - (0x7fffffff % range)); do { num = _RngRandom(); } while (num >= securemax); // Reject numbers that would cause bias return min + (num % range); // Return a uniformly distributed value in [min, max] } // Returns a uniformly distributed float in the range [min, max] // Due to the limited precision of floating-point numbers, two or more adjacent random integers // may produce the same floating-point number after computation. // Therefore, this method cannot generate truly uniformly distributed decimals, especially at the range endpoints. function RandFloatUniformDistribution(min, max) { // Generate a uniformly distributed random decimal in the range [0, 1] local randomFloat = _RngRandom().tofloat() / 0x7fffffff; return min + (randomFloat * (max - min)); // Scale the range to the target range } // Returns a random number following a normal distribution (Gaussian distribution) // mean: The mean of the normal distribution // std_dev: The standard deviation of the normal distribution function RandFloatNormalDistribution(mean, std_dev) { local u1 = _RngRandom().tofloat() / 0x7fffffff; // Uniform float in [0,1] local u2 = _RngRandom().tofloat() / 0x7fffffff; // Uniform float in [0,1] // Box-Muller transform to obtain standard normal distribution // sqrt(), log(), and cos() are math functions. // The code works in AS:RD. If it doesn't work for your source engine game add-on, // try to find the corresponding functions for your game. local z0 = sqrt(-2 * log(u1)) * cos(2 * 3.14159 * u2); // Transform Z0 to have the desired mean and standard deviation return mean + z0 * std_dev; // Transform to the target distribution } Example Usage function OnGameplayStart() { RngSetSeed(GetLocalTime()); //This will provide a random seed to the MT19937 engine. //RngSetSeed(12345);// Or you can set the seed for reproducibility for debugging purpos. // Generate a random integer in the range [1, 100] local randInt = RandIntUniformDistribution(1, 100); printl("Random Integer in [1, 100]: " + randInt); // Generate a random float in the range [0.0, 1.0] local randFloat = RandFloatUniformDistribution(0.0, 1.0); printl("Random Float in [0.0, 1.0]: " + randFloat); // Generate a random float in a normal distribution with mean = 10 and std_dev = 2 local randNormal = RandFloatNormalDistribution(10, 2); printl("Random Float with Normal Distribution (mean=10, std_dev=2): " + randNormal); } // Return the current time in seconds function GetLocalTime() { local localTime = {}; LocalTime(localTime); return localTime.dayofyear * 86400 + localTime.hour * 3600 + localTime.minute * 60 + localTime.second; } Output Example Random Integer in [1, 100]: 42 Random Float in [0.0, 1.0]: 0.718928 Random Float with Normal Distribution (mean=10, std_dev=2): 8.634879

评论

共0条评论
face
inputImg
相关阅读
最新更新

【编辑器教学】真实物理开关

2024-12-02 03:393赞 · 0评论

交互板在手,超绝打卡点我有

2024-12-10 02:116赞 · 4评论

GEM编辑器基础教程

这是一份关于如何开始使用《战争之人:突击小队2》GEM编辑器基础功能的入门教程。注意:已为每个显示内容添加了单独链接。 截至2016年4月21日,本指南已再次更…

2026-02-17 16:000赞 · 0评论

爆肝!!!!震惊某创作者肝一张图,肝了有半年还没出图🤓☝️

好累好累,不想肝,不想肝,不想肝,不想肝,不想肝,不想肝,不想肝,不想肝,不想肝,不想肝,不想肝,不想肝,不想肝,不想肝,碎碎念,不想肝🥺

2025-11-29 13:0767赞 · 9评论

星际争霸无限矿 星际争霸富矿怎么选

星际争霸是一款备受玩家喜爱的游戏。关于如何选择无限矿的玩法攻略,每场游戏都是独特的,策略的选择和调整需要根据具体情况灵活变化。通过不断练习和反思,你会逐渐掌握选…

2025-10-10 13:200赞 · 0评论

《装甲军团2》战斗场景编辑器用户手册

《装甲军团2》战斗场景编辑器用户手册 基础操作 新建战斗场景要创建一个新的战斗场景,可使用以下任一方式: 在主菜单中选择 File->New 点击工具栏上…

2026-02-19 13:000赞 · 0评论

《命令与征服:重制版》触发器指南

《命令与征服:泰伯利亚黎明》触发器权威指南 关于 重制版附带的编辑器存在诸多问题(内部工具公开后出现此类问题并不意外),但开发者明智地向社区公开了源代码。目前已…

2026-02-15 07:000赞 · 0评论

啊哈世界:可以自己配音的游戏你见过吗~?拍剧更有创意啦

地图的编辑玩法居然比米加还多,每个地图的位置都能自己摆设!!

2023-07-26 10:4210498赞 · 3964评论

蛋仔派对乐园工坊 从0开始学乐园工坊,第一步熟悉按键

2025-11-30 22:490赞 · 0评论

进阶版攻略!老图还能这样爆改?

2024-11-07 06:33314赞 · 16评论
暂无更多

最新更新

  • 机器人基础 — 你将学习: 如何添加/移除机器人 机器人装备相关信息 机器人语音指令/热键 机器人对周围事件的反应方式 机器人控制台指令 其他非必要信息 简介——杰拉尔德·布鲁…
  • 专业人士配置 — Здесь приводятся файлы конфигов которые используют профи для игры на самых высок…
  • 《异形丛生:反应下降》服务器搭建指南 — 搭建并设置游戏专用服务器(Dedicated Server)的指南。 前言 目前网络上的中文《Alien Swarm: Reactive Drop》服务器搭建教…
  • 最高难度入门基础指南 — 本指南面向新玩家或有一定经验的玩家,旨在帮助他们学习如何游玩《Reactive Drop》。尽管本指南侧重于最高难度(Brutal-Asalto-Fuego a…
  • Battle-Tested 成就指南 — 一份为解锁成就而“了结此生”的方法清单! 简介 显然,不少玩家在游戏中难以找到25种不同的死亡方式来解锁“身经百战”成就。所以我来为社区贡献一份“死亡指南”,告…
  • 制作材料完全指南 — 游戏内所有制作材料的完整列表! 如何获取制作材料 制作材料可在任务中找到,随机生成于地图各处。你能找到的材料各不相同,且稀有度各异。 批量材料 批量材料完整列表…
  • 官方感染指南 — Infection is a Deathmatch Challenge/Game Mode that officially became a part of t…
  • 速通成就获取指南 — 本指南将帮助你完成速通成就。 前言 为准备完成速通成就,你可以参考以下指南: 速通指南 高级游戏技巧:《反恐精英:反应行动》 以下所有信息均来自个人经验及上述指…
  • 如何以第一人称视角游玩 — 如何启用和禁用第一人称视角的简易指南 启用开发者控制台 确保已启用开发者控制台。 你可以通过进入选项,然后选择键盘和鼠标来启用它。
  • 巴士底狱【简易指南】 — 如何游玩《ASBI+》中的巴士底狱 数据与展示 里昂“巴士底狱”