V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
cj323
V2EX  ›  程序员

函数式编程适不适合游戏开发

  •  
  •   cj323 · 4 天前 · 3798 次点击

    之前写小游戏(非专业,纯玩)都是习惯面向对象。大概感觉是这样

    class Object()
      #states: [position, health, direction...]
      #methods: [move, serializer]
            
    class Player(Object)
      #player_methods: [attack...]
    
    class Boss(Object)
      #boss_methods: [...]
    
    
    p1, p2 = new Player(), new Player()
    boss = new Boss()
    
    p1.move(..)
    p2.move(..)
    boss.attack(..)
    Renderer.render(p1, p2, boss)
    

    学了几天 elixir 后发现函数式也挺顺手,但是不知道有没有实际用函数式开发游戏的。

    global_state<Immutable> {
      player1_pos: ..
      player1_health: ..
      player2_pos: ..
      player2_health: ..
      boss_pos: ..
      boss_health: ..
      ...
    }
    
    fn move: state -> new_state
    fn move_player: () -> state -> new_state
    fn move_player_by_num: num -> () -> state -> new_state
    fn move_boss: state -> new_state
    fn boss_attack: state -> new_state
    
    global_state
      |> move_player_by_num(1)
      |> move_player_by_num(2)
      |> move_boss
      |> bos_attack
      |> render
    

    感觉除了内存占用大一些没其他坏处,有有经验的分享下么?

    30 条回复    2025-01-15 00:53:04 +08:00
    VchentozV
        1
    VchentozV  
       4 天前
    以前 vczh 安利我函数式编程, 我不知道学了有什么用, 同问.
    xgdgsc
        2
    xgdgsc  
       4 天前 via Android
    ymmud
        4
    ymmud  
       4 天前
    有助于提升代码质量
    VchentozV
        5
    VchentozV  
       4 天前
    @ymmud 国际上有哪个大公司在使用吗? 有什么工业界实际的项目在运用吗?
    GeruzoniAnsasu
        6
    GeruzoniAnsasu  
       4 天前
    https://v2ex.com/t/847038#r_11567399

    看场景。函数式编程你明白是在定义一种变量约束关系,与从原始数据到目标数据的 transform 就好。
    VchentozV
        7
    VchentozV  
       4 天前
    @GeruzoniAnsasu linq 我也写过, 除了写法非常潮, 很漂亮, 但是别人看不懂 :-0
    VchentozV
        8
    VchentozV  
       4 天前
    @GeruzoniAnsasu 反正 linq 写多了也挺轻松, 比如 lodash, 但是还是喜欢 linux c 的抽象, 简单明了, 但是不知道普通的程序员维护起来轻松吗?

    我观测的标准就是, 是否流行, 有很多的项目.
    zdw189803631
        9
    zdw189803631  
       4 天前   ❤️ 1
    我觉得更适合写业务层,丢失了一部分性能,换来了代码的可行度,但是有些人写的 函数式也没啥可读性,写起来比较爽是真的,不容易出 bug
    ohoh
        10
    ohoh  
       4 天前   ❤️ 1
    ======================
    张三丰向张无忌传授一套太极剑法,一路剑法使完,竟无一人喝彩,各人尽皆诧异:“这等慢吞吞、软绵绵的剑法,如何用来对敌过招”。还以为是张真人有意放慢了招数,好让张无忌瞧个明白。
    只听张三丰问道:“孩儿,你瞧明白了没有?” 无忌答道:“看清楚了。” 张三丰道:“都记得了没有?” 张无忌答道:“已忘记了一小半。” 张三丰道:“好,那也难为你了。你自己去想想吧 。” 张无忌低头默想。
    过了一会,张三丰问道:“现下怎样了?” 张无忌道:“已忘了一大半了。" 周颠等人皆急:“刚学的剑法都忘了一大半,这可如何迎敌?” 便请张三丰重新传授一遍。
    张三丰微笑,再使出一路相同的剑法。张无忌沉思一会,睁开眼:“我已忘得干干净净。” 众人皆惊,唯张三丰独喜。随即张无忌拿剑迎敌,大胜。
    =====================

    这是摘自《倚天屠龙记》,张三丰教于张无忌的三个境界。编程也是如此。
    第一层,学习语言语法和规则,理解编程范式,巩固基础核心。
    第二层,熟练掌握,灵活运用,理解设计模式的运用。
    第三层,随心所欲,信手拈来。

    第三层最终归于平淡,什么项目用什么,什么场景用什么,不再刻意追求使用什么工具,什么语言,用了什么设计模式,一切都是基于专业的透彻理解,其他的都是对经验的抽象后的总结。

    前人告诉了你这样可以如何如何,有天赋的比如张无忌就能一点就通,我等凡夫俗子通常需要不断踩坑才能深刻体会。
    Joey2022
        11
    Joey2022  
       4 天前
    erlang 就是很典型的函数时编程,且在游戏开发领域很常用,尤其是那种 MMORPG 的网游,不过主要原因还是 erlang 的 actor 方式的通信模型
    archxm
        12
    archxm  
       4 天前 via Android
    @VchentozV 可以搞基
    MoYi123
        13
    MoYi123  
       4 天前
    用 erlang/elixir 的很大一部分是做游戏后端的.
    xarthur
        14
    xarthur  
       4 天前 via iPhone   ❤️ 1
    其实游戏编程还蛮适合函数式的,因为游戏其实就是个巨大的有限状态自动机,各种游戏操作只是对状态的变换罢了。
    maichael
        15
    maichael  
       4 天前
    没写过游戏,但是我觉得无论面向对象的方式写,还是函数式的方式写,最后的输出的“结果”是一样的,那其实就只有代码的“样貌”不同,对于个人开发者而言,要对比的差别应该是可读性、可维护性,以及写代码时的心智负担等,如果是团队开发来说,要考虑就更多了。
    mahaoqu
        16
    mahaoqu  
       4 天前
    其实 F# 嵌入 Godot 是非常可行的。我记得有个 Up 发过视频。
    sunny352787
        17
    sunny352787  
       4 天前
    可以,但没必要,就现在游戏圈里能找到的牛马的技术水平,能把面向对象写明白就不错了
    qcbf111
        18
    qcbf111  
       4 天前   ❤️ 1
    不适合,中、大型游戏性能完全达不到要求,可能适合简单的小游戏。
    函数式编程是放弃一部分单体性能换取方便的极致的高并发,因为不可变性无副作用,所有数据都依靠最基础的数据源计算而不像面向对象有很多中间状态,这是很适合服务端开发的,但非常不适合客户端开发。
    比如游戏生命值,函数式是每次获取都现场计算基础生命值+buff+装备等等得到最终生命值,而游戏普遍做法是有一个最终生命值的状态,每次 buff ,装备都去修改这个状态,获取最终生命值直接获取这个状态。
    Hypn0s
        19
    Hypn0s  
       4 天前
    你写的这个代码,越看越有 ECS 的味道
    ccpp132
        20
    ccpp132  
       4 天前   ❤️ 1
    游戏还是属于 state change 很多的场景,其实不太合适。
    functional 想法用在一些接口设计还可以,纯函数式就不太好用

    函数式编程还是在做编译器和解释器的场景用的比较合适
    yazinnnn0
        21
    yazinnnn0  
       4 天前   ❤️ 1
    写 server 还是写 client?
    感觉都不合适, 游戏天生自带了一吨外部状态, 天生和函数式理念不符
    mightybruce
        22
    mightybruce  
       4 天前
    还是写得太少了,在高手面前编程范式都是可以挑选的,而不是拘泥于一种。上面也有人提到了 erlang, elixir 很多人都用来做游戏后端, 给一个 20 年老程序员 网易游戏总监云飞的 blog 地址,
    他之前搞得 skynet 框架 正是借鉴了 erlang 的特点(比如热更新)。他写这些东西的时候已经是 10 年前了。
    https://blog.codingnow.com/2013/08/skynet_update.html
    c0t
        23
    c0t  
       4 天前 via iPhone
    客户端肯定不合适,至少不能纯用某个语言来写,连个事实标准的图形 api binding 都没有,要我自己新造个轮子来解析 vulkan xml ,我还真嫌麻烦。

    至于 elixir ,要例子的话,我记得一些日本公司有拿来做服务端用,在他们一些技术博客上看过,比如 cygames?

    这一堆函数式语言里我觉得最有双端生产力的是 F#,只可惜 BDFL 自己都不在乎自己的成果了,微软剩下那几个全职开发同时负责编译器和内部支持,完全忙不过来,F#最后只会越来越和 C#脱节
    mightybruce
        24
    mightybruce  
       4 天前
    对 skynet https://github.com/cloudwu/skynet/
    实际封装后的游戏服务器例子
    https://github.com/li5414/RillServer
    kakki
        25
    kakki  
       4 天前   ❤️ 1
    性能会跟不上,之前知乎看过某个帖子,也是大佬重构 erlang 写的后端极大的提高并发量, c++ 在性能敏感场景就是这么吊你不得不服.
    tubinorg
        26
    tubinorg  
       4 天前
    用 erlang 的好处就是
    1. 并发,每个进程都有自己的队列,收发消息简单粗暴,进程隔离
    2. 监督进程可以管理子进程
    3. 热更新

    对于性能
    非得需要极致性能,那么 + c + zig + rust
    对于项目
    所有的大型逻辑项目,都是屎山堆屎
    fengjianxinghun
        27
    fengjianxinghun  
       4 天前 via iPhone
    顽皮狗的游戏逻辑用一个 lisp 方言脚本开发,详见游戏引擎架构那本书
    tubinorg
        28
    tubinorg  
       4 天前
    @tubinorg 坏处是 这 tm 啥 jb 符号语言
    BALDOOR
        29
    BALDOOR  
       4 天前   ❤️ 1
    我写这玩意 10 年了,爽和蛋疼参半吧
    性能不行,我已经编译甚至在 beam asm 层面优化过,哪怕跑在 jit 下都很差,计算密集场景需要用 c 写 nif
    有一次,一个小项目,复杂度很低,我用 typescript+rust 复刻了一遍,直接跑了超过 10 倍的性能
    适合一些性能不敏感的,但随意并发需求大的,IO 打满的场景
    不要迷信所谓的函数式之类的,从工程角度来说大多数都比较差,难学也是其中之一
    netabare
        30
    netabare  
       3 天前 via iPhone
    游戏开发需要处理大量对象吧,似乎是计算密集型的任务,纯函数式编程会产生巨量生命周期极短的对象,似乎和游戏开发不太合得来。

    不过要是写小型游戏或者后端应该会很爽,而且 FRP 和 Signal 之类的工具表现力也很强。不过能不能习惯就是另一个问题了。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1739 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 16:40 · PVG 00:40 · LAX 08:40 · JFK 11:40
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.