SkyMP (Skyrim Multiplayer)

repository·main·Indexed 43 days ago

https://github.com/skyrim-multiplayer/skymp

An open-source multiplayer mod for Skyrim built upon the SkyrimPlatform. It enables mod development using TypeScript and Chromium, allowing creators to implement modern tech stacks, async support, and custom UIs within the Skyrim environment.

Tokens
36.2K
Snippets
130
Records
185
Agent score
55%

What's inside SkyMP

  1. Overview of Skyrim Platform

    main

    Skyrim Platform (SP) is a framework that allows developers to create Skyrim mods using JavaScript and TypeScript. It provides a modern development environment for modding, featuring high-level language features, rapid iteration tools, and web technologies for UI development.

    Key Features for Developers

    • Modern Tech Stack: Use JSON, RegExp, classes, functional programming, and npm packages.
    • Hotreload: The platform watches plugins by default. Saving your code (Ctrl+S) allows you to test changes in-game immediately without restarting.
    • Async Support: Native support for Promises and async/await for asynchronous Papyrus functions (e.g., Utility.wait, ObjectReference.setPosition).
    • UI Development: Uses Chromium Embedded Framework, enabling the creation of in-game UIs using React, VueJS, etc.
    • SKSE Compatibility: Call 3rd party SKSE functions natively from JavaScript/TypeScript.
    • Safety: Protects against common issues like null pointers and threading problems.

    Supported Games

    • Steam latest (currently Skyrim SE/AE 1.6.1170)
    • Skyrim SE/AE 1.6.640
    • Skyrim SE 1.5.97.0.8 (Deprecated; no longer accepting bug reports)
  2. Overview of SkyMP

    main
    SkyMP is an open-source multiplayer mod for Skyrim. It is built upon the SkyrimPlatform, a development tool designed to allow creators to build Skyrim mods using TypeScript and Chromium. This repository contains the full source code to facilitate local setup and community contributions.
  3. Overview of Skyrim Platform

    main
    Skyrim Platform is a modding tool for Skyrim that enables developers to write scripts using JavaScript or TypeScript. It provides a bridge between the game engine and modern scripting languages, allowing for complex logic, UI, and integration that goes beyond traditional scripting. The skymp client itself is implemented as a mod using this platform.
  4. Understand the evolution of SkyMP

    main

    SkyMP has evolved through several major architectural iterations, moving from basic C++ movement synchronization to a modern TypeScript-based platform.

    Key historical milestones include:

    • SkyMP 0.9/1.0+: C++ based with a Lua scripting system.
    • SkyMP 2.0+: Introduced a stateless server architecture using MongoDB and client-side Lua scripting.
    • SkyMP 3: Introduced a NodeJS-based scripting system and an asynchronous multiplayer games framework.
    • SkyMP 5 (Current): Uses C++ and TypeScript. It introduces the Skyrim Platform, a TypeScript environment for Skyrim SE that enables rapid plugin development with Hot Reload support.
  5. Understand the SkyMP build system and project structure

    main

    SkyMP is a multi-language project primarily using C++ and TypeScript. The build system is CMake-based.

    When building the entire project via CMake, the system is configured to automatically invoke npm commands for TypeScript subprojects to handle dependency installation and compilation.

    Project Organization Rules:

    • All project folders use kebab-case (e.g., skyrim-platform).
    • Every project folder must contain a CMakeLists.txt file.
    • The CMakeLists.txt must define a build target that matches the project's folder name.
  6. Use the Properties System with mp.get and mp.set

    main
    The SkyMP API provides a property system that allows scripts to interact with object data. You can access and manipulate properties using mp.get to retrieve values and mp.set to modify them. This system supports both custom properties added by your own code and 'built-in' properties defined by the SkyMP server.
  7. Communicate from the browser to the game

    main

    To send data from the web browser context back to the SkyrimPlatform (SP) context, use window.skyrimPlatform.sendMessage. This function accepts zero or more JSON-serializable values.

    When sendMessage is called in the browser, it triggers a browserMessage event in the SP context. You can listen for this event to handle incoming data.

    // In the browser (HTML/JS context)
    window.skyrimPlatform.sendMessage({ foo: 'bar' });
    window.skyrimPlatform.sendMessage(1, 2, 3, "yay");
    // In the SkyrimPlatform context (TS/Plugin context)
    on("browserMessage", (event) => {
      console.log(event.arguments);
    });
  8. Understand the default TES5DamageFormula implementation

    main

    The current default implementation (TES5DamageFormula) uses a simplified version of the vanilla formula. It calculates damage using two main steps: incoming damage determination and armor reduction.

    Incoming Damage

    Determines the base damage based on whether the attack was unarmed: incomingDamage = isUnarmed ? raceUnarmedDamage : baseWeaponDamage;

    Armor Damage Reduction

    Armor reduction is calculated by summing all armor ratings and magic armor ratings (the sum of magnitudes of enchantments with the damage resist magic effect):

    armorRating = armorRating1 + armorRating2 + ... + armorRatingN + magicArmorRating;

    Final damage is then calculated using the following formula: receivedDamage = incomingDamage * 0.01 * (100 - std::min(armorRating * fArmorScalingFactor, fMaxArmorRating));

    Default Constants:

    • fMaxArmorRating: 80 (GMST:00037DEB)
    • fArmorScalingFactor: 0.12 (GMST:00021A72)
    // Armor reduction logic summary
    receivedDamage = incomingDamage * 0.01 * (100 - std::min(armorRating * fArmorScalingFactor, fMaxArmorRating));
  9. Optimize hooks using filtering parameters

    main

    Hooking is expensive because it requires entering the JavaScript context. To improve performance, use filtering parameters to allow the SkyrimPlatform side to discard unneeded events before they reach JavaScript.

    When calling .add(), you can provide:

    1. minSelfId: Minimum ID range for filtering.
    2. maxSelfId: Maximum ID range for filtering.
    3. eventPattern: A string pattern for the event name.

    Rules for eventPattern:

    • Supports a single wildcard * (e.g., "*Sleep*" is not supported; use "*" or a specific name).
    • Only one wildcard is allowed. Using two or more wildcards will result in an exception.
    import { hooks, printConsole } from "skyrimPlatform";
    
    // Good: No JS is triggered until selfId is 0x14 and event name matches "*"
    hooks.sendAnimationEvent.add({
      enter(ctx) {
        printConsole("Player's anim:", ctx.animEventName);
      },
      leave(ctx) {}
    }, /* minSelfId = */ 0x14, /* maxSelfId = */ 0x14, /*eventPattern = */ "*");
  10. Develop Skyrim plugins using Skyrim Platform

    main

    The current iteration of the project (SkyMP 5) utilizes the Skyrim Platform, which provides a TypeScript environment for Skyrim Special Edition (SE).

    This platform is designed for rapid prototyping and plugin development, featuring:

    • TypeScript Support: Allows coding Skyrim plugins in TypeScript.
    • Hot Reload: Enables fast iteration by reloading code changes without restarting the game environment.