Game engine behind Sea Dogs, Pirates of the Caribbean and Age of Pirates games.

Storm-Engine

Game engine behind Sea Dogs, Pirates of the Caribbean and Age of Pirates games.

Join the chat at https://discord.gg/jmwETPGFRe GitHub Actions Build Status

Supported games

Building the project

You need to install Conan and add it to the %PATH% environment variable. Also, make sure you have the following Visual Studio components installed:

  • C++ CMake Tools for Windows
  • C++ Clang Compiler for Windows
  • C++ MFC for latest v142 build tools (x86 & x64)

Open the repo root as a CMake project in Visual Studio 2019 and select engine.exe as a startup item.

For running engine.exe you need to have DirectX 9 runtime libraries installed.

Roadmap

Since our development team is small, we want to reduce the amount of code we have to maintain. For this reason, we decided to rely on the C++ standard library or third-party libraries if possible.

Some things that we are going to do:

  • Replace a custom math library with a third-party one, e.g. glm.
  • Replace custom rendering code with a bgfx library.
  • Replace custom input handling code with a third-party library, e.g. gainput.
  • Replace custom data structures with C++ standard types.
  • Replace a custom scripting language with Lua.
  • Replace ini config files with JSON.
  • Replace custom binary asset formats with standard ones.

Contributing

If you'd like to get involved, don't hesitate to contact us. Pull requests and any other kind of help are more than welcome as well.

If you want to start with small contributions, updating the code to the modern C++ and fixing compiler warnings are very much appeciated.

License

GPL-3.0 License

Comments
  • Overhauling of build system

    Overhauling of build system

    This is a quite major update ( not in terms of size though :) ) that almost does not affect the code but IMO this is a necessary step for further refactoring and cleanup. It mostly consists of three parts:

    1. implement "autocmake" system called "StormSetup" similar to one that @Hammie added, but considering SE-specific things. It is 'globbing' based but with enabled CONFIGURE_DEPENDS
    2. bring back Thunderstom classes registry to get rid of "vmainit". Since we are on static-libs now this is kind of a workaround too. but it is lesser of two evils and also conforms the original architecture
    3. move externals to artifactory

    It is far from a finished state but I need reviews and comments on that so I can fix and finish the stuff.

    Known issues ATM are: resources are not compiled - to be automated via StormSetup tests are not compiled - to be automated via StormSetup clang build is likely not working (I did not test that) - I think StormSetup needs tweaking to support it

    Please, take a look and do not hesitate to leave a comment

  • CI: disable to build fix/* and feature/* branches

    CI: disable to build fix/* and feature/* branches

    It looks like CI is running too often. If we make it as rule to create small branches as a fix/* or feature/*, then these changes will help reduce/speed up the build.

    Here is docs about CI branches: https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#example-including-branches-and-tags

  • Restore default behaviour for script function SendMessage

    Restore default behaviour for script function SendMessage

    SendMessage's default behavior when first argument was not a valid entity was to return 0, according to this line. This was changed in thunderstorm. Some code in TEHO stopped functioning because of that, for example F2 interface wouldn't open on worldmap. While this is something that can and should be fixed in scripts, I'm pretty sure COAS relied on SendMessage returning 0 too, so this behavior should be reverted for compatibility reasons.

  • fix crash on Ship_HullDamage call (event_name

    fix crash on Ship_HullDamage call (event_name "ShpHullDamage")

    How to reproduce crash: Load attached save and fight with enemy in sea. Open_sea-SAVE.zip Crash sometimes happens when cannonballs hit your ship.

    How it looks like in debugger: unknown

  • Linux related changes part 1

    Linux related changes part 1

    The Linux version is ready and works well enough in my opinion, so it's time to merge. I decided to split the changes into several parts. In this (first) part there will be small changes and additional functions that are needed for building and correct working engine on Linux.

  • Overhaul logging and crash handling

    Overhaul logging and crash handling

    What is done:

    • Enable logging by default
    • Flush in a separate thread every 5 seconds (configurable in code so far) after core iteration run
    • Fixup sentry/crashpad, attach archived logging folder

    There is still some related things to tweak. Mostly to make options configurable without rebuilding. But this is good to merge asap and eventually do the rest.

  • Programming style guide

    Programming style guide

    Add initial style guide, based on https://github.com/lefticus/cppbestpractices

    It is quite outline, so we should add more сlarifications (strings, smart pointers, etc.) later.

  • Use SDL for window and event handling.

    Use SDL for window and event handling.

    This PR Introduces window and OS event handling abstraction - WindowManager class. And its implementation using SDL.

    WindowManager defines OS-agnostic event struct (WMEvent), keyboard keys, etc. It handle OS events and can forward it to clients (Core, PCS_Control) using callbacks. Also, it provides methods to request current input state, replacing WinAPI's GetAsyncKeyState()

    Currently, it uses WinAPI's virtual key (VK_*) for keycodes for compatibility and converts them from/to SDL scancodes (aka "USB scancodes"). This conversion can be eliminated if we replace keycodes everywhere in code, including scripts which is work for future.

    pcs_controller and Core updated to use this new class. Core initialization code is messed, so WM is initialized outside of it for now.

    Tested for some time on TEHO - seems everything (sailing, walk, battle, gui) works same as before,

    Feel free to criticize this new approach.

    P.S.: There is https://github.com/storm-devs/storm-engine/pull/40 which also adds SDL, I wil rebase this PR when we will decide what to do with SDL.

  • ini: fix reading ini files with LF endings

    ini: fix reading ini files with LF endings

    I will show the error on the example of reading the file loclighter.ini Option 1 CRLF:

    ; Loading Location lighter/r/n
    loading = 1/r/n
    ; Enable automatic trace auto preparing data/r/n
    

    End of the first pass of the loop before executing the code n += offset; we have: n = 0 and offset = 25

    After adding n += offset; and n++ from the loop we got: n = 26 and this indicates / n (which became/ 0). It turns out that we do not fall into the condition: if (file_data [n]! = 0)

    Option 2 LF:

    ; Loading Location lighter/n
    loading = 1/n
    ; Enable automatic trace auto preparing data/n
    

    End of the first pass through the loop before executing the code n + = offset; we have: n = 0 and offset = 25

    After adding n += offset; and n++ from the loop we got: n = 26 and this points to l (first character from 2nd line) and and it turns out that we get into this condition: if (file_data [n]! = 0) and execute it until we get to the end of the line / 0.

    Thus, we always lose the second line from the ini file.

    As a check, you can take a close look at the code before the changes:

        for (n = 0; n < file_size; n++)
        {
            if (n == 0)
            {
                data_PTR = file_data;
            }
            else
            {
                if (file_data[n] != 0)
                    continue;
                if ((n + 1) >= file_size)
                    break; // end of file
                if (file_data[n + 1] == 0)
                    continue; // separator zero
                data_PTR = file_data + n + 1;
    

    And the code after the changes:

        for (n = -1; n < file_size; n++)
        {
            if (n == -1)
            {
                data_PTR = file_data + n + 1; // is the same as data_PTR = file_data;
            }
            else
            {
                if (file_data[n] != 0)
                    continue;
                if ((n + 1) >= file_size)
                    break; // end of file
                if (file_data[n + 1] == 0)
                    continue; // separator zero
                data_PTR = file_data + n + 1;
    

    And then data_PTR = file_data + n + 1; could be used in 2 places.

    Russian version:

    Покажу ошибку на примере чтения файла loclighter.ini Вариант 1 CRLF:

    ;Loading Location lighter/r/n
    loading = 1/r/n
    ;Enable automatic trace auto preparing data/r/n
    

    Конец первого прохода цикла до выполнения кода n += offset; мы имеем: n = 0 и offset = 25

    После сложения n += offset; и n++ от цикла получаем: n = 26 и это указывает на /n (который превратился в /0). Получается, что мы не попадаем в условие: if (file_data[n] != 0)

    Вариант 2 LF:

    ;Loading Location lighter/n
    loading = 1/n
    ;Enable automatic trace auto preparing data/n
    

    Конец первого прохода цикла до выполнения кода n += offset; n = 0 и offset = 25

    После сложения n += offset; и n++ от цикла получаем: n = 26 и это указывает на l (первый символ из 2ой строки) и и получается, что мы попадаем в это условие: if (file_data[n] != 0) и выполняем его до тех пор, пока не встанем на конец строки /0.

    Таким образом мы всегда теряем вторую строку из ini файла.

    В качестве проверки можно внимательно посмотреть на код до изменени:

        for (n = 0; n < file_size; n++)
        {
            if (n == 0)
            {
                data_PTR = file_data;
            }
            else
            {
                if (file_data[n] != 0)
                    continue;
                if ((n + 1) >= file_size)
                    break; // end of file
                if (file_data[n + 1] == 0)
                    continue; // separator zero
                data_PTR = file_data + n + 1;
    

    И код после изменений:

        for (n = -1; n < file_size; n++)
        {
            if (n == -1)
            {
                data_PTR = file_data + n + 1; // is the same as data_PTR = file_data;
            }
            else
            {
                if (file_data[n] != 0)
                    continue;
                if ((n + 1) >= file_size)
                    break; // end of file
                if (file_data[n + 1] == 0)
                    continue; // separator zero
                data_PTR = file_data + n + 1;
    

    И тогда data_PTR = file_data + n + 1; можно было бы использовать в 2 местах.

  • Fix capitalization of filenames in CMake configuration

    Fix capitalization of filenames in CMake configuration

    Fixes the capitalization of filenames in the CMake configuration.

    Also adds missing includes for OSWindow when compiling with gcc, and disables the windows-specific options for unit tests.

  • engine: remove floating point precision format when converting to string

    engine: remove floating point precision format when converting to string

    gcvt was replaced with fmt::format with the same precision. fmt::format follows sprintf semantic; it cannot match gcvt behaviour without manual transformation. Also, I see no point in clipping float with a buffer size of 5 in general. So, I removed precision in order to remove surplus 'width' precision. Let's see if it will bloat something due to potentially long mantissa

  • Linux related changes: resource loading + sound

    Linux related changes: resource loading + sound

    This is last PR in Linux series. After merging it game should be playable on Linux. There are still bugs, which will be fixed in future:

    • No screenshots by pressing F8. Low priority. I think that I can fix it soon, but may be with only 1 format (like png or jpeg).
    • Fix archiving with 7za. Low priority.
    • Fix steam integrations. Mid priority.
    • No intro video. Mid priority. This is require rewriting 1 class (libs/xinterface/src/aviplayer) and adding a dependency on libmpg123 or ffmpeg.
    • ~~Fix LifecycleDiagnosticsService and check if message "Unable to initialize lifecycle service!" still happens. Mid priority.~~ Fixed.
    • ~~Flickering shadow from the main character. Top priority.~~ Fixed.
    • ~~Strange behavior of sailors on the ship. Top priority.~~ Fixed.

    Also I'll add Linux Release build to CI and optimization flags in future.

  • Feature: understand why bPostProcessEnabled is false and what will happen after enabling it

    Feature: understand why bPostProcessEnabled is false and what will happen after enabling it

    I would like to understand:

    • why bPostProcessEnabled is false?
    • should I rewrite it from asm to HLSL?
    • what will happen after enabling it?

    Some log from discord - already known information:

    q4a — 03.05.2021 I wanted to understand what current shaders do and started with small one: https://github.com/storm-devs/storm-engine/blob/develop/src/techniques/postprocess/postprocess_shader.h But looks like it was disabled and newer calls because of this line commented out: https://github.com/storm-devs/storm-engine/blob/develop/src/libs/renderer/sdevice.cpp#L361 It was modified in this commit: https://github.com/storm-devs/storm-engine/commit/02d86a97a369685a7b959cecf93821031140fde0#diff-d19d7f5cf5224e1c43653497eae01f143fa786809b3c5bcf651d98e13db8720aL391 and I would like to know - should I ignore this shader or better remove it?

    kb31 — 03.05.2021 Honestly, I do not remember why did I disable it Likely it was causing issues I think we should try to turn it back anyway

    q4a — 03.05.2021 when I turned on it in code and engine.ini - I got black screen instead of intro video

    kb31 — 03.05.2021 That might be because some code is missing from dx9render.cpp...

    cooodesloth — 03.05.2021 @q4a you could also try to find a related commit in the thunderstorm fork to know exactly why it was disabled

    q4a — 03.05.2021 I found: https://github.com/storm-devs/thunderstorm-engine/commit/696d2eb3ad68e658b8c54ffd43312ed19aae873a

    cooodesloth — 03.05.2021 seems like it was disabled even before https://github.com/storm-devs/thunderstorm-engine/commit/696d2eb3ad68e658b8c54ffd43312ed19aae873a#diff-7baa1c729b48852f3fa56b26eb0338225e2071f7e2ae4697c86835bccb8348e7L736

    kb31 — 03.05.2021 Yeah as I said I disabled it long time ago As I recall now, I likely tried to achieve correct sequence of directx device free So this was not meant to be disabled forever, that's why the shader was not removed

  • [dxvk] Porting on Linux using dxvk tracking issue

    [dxvk] Porting on Linux using dxvk tracking issue

    Here will be current lists of needed fixes for Linux port of engine using dxvk.

    Current source code of dxvk port is here: https://github.com/storm-devs/storm-engine/tree/dxvk

    Started status: there is 113 #ifdef marked with FIX_LINUX which should be replaces with proper implementations, but engine already build fine with CLANG 11 and partially show main menu background storm-linux-main-screen

    Current status: cur-status

    113 marked FIX_LINUX tasks (from most important to less):

    • [x] 19 for FIX_LINUX ID3DXEffect. Pushed workaround: CTechnique: + precompiled shaders. Check FIX_LINUX Effects
    • [ ] 01 for FIX_LINUX D3DXCreateTextureFromFileA: is it used at least somehow?
    • [x] 01 for FIX_LINUX D3DXCreateTextureFromFileInMemoryEx: unused, created PR: https://github.com/storm-devs/storm-engine/pull/347
    • [x] 04 for FIX_LINUX HBITMAP: unused, created PR: https://github.com/storm-devs/storm-engine/pull/347
    • [ ] 04 for FIX_LINUX Screenshot: I hope that SDL has some useful funcs for taking screenshots
    • [ ] 02 for FIX_LINUX ReleaseDC: not sure, but may be important
    • [ ] 04 for FIX_LINUX VirtualKey: There is dilemma: we can keep VirtualKeys for c-files in PROGRAM folder to maintain old mods or replace all VirtualKeys, because less code == less errors. Current decision - keep VirtualKeys: https://github.com/storm-devs/storm-engine/pull/328
    • [ ] 04 for FIX_LINUX HINSTANCE: for correct handling window and other: https://github.com/storm-devs/storm-engine/pull/366
    • [ ] 04 for FIX_LINUX Cursor: port all Cursor stuff to SDL
    • [ ] 10 for FIX_LINUX GetTickCount: I hope that we will find old branch/changes where is this changes already made
    • [ ] 03 for FIX_LINUX sentry_options: few Windows only direct calls to crashpad_handler.exe
    • [ ] 01 for FIX_LINUX WideCharToMultiByte: some old conversation
    • [ ] 01 for FIX_LINUX MultiByteToWideChar: some old conversation
    • [ ] 08 for FIX_LINUX DirectXMath: one DirectXMath call in AVX/SSE2 ifdef. I created quick workaround (this increased 08 for FIX_LINUX DirectXMath from 2 to 8), but I'll need to replace it with this lib: https://github.com/nfrechette/rtm
    • [ ] 04 for FIX_LINUX DxErr.h: few error handling, may be already in DXVK?
    • [ ] 02 for FIX_LINUX _flushall: not sure
    • [ ] 01 for FIX_LINUX RDTSC_*: need to test SDL_GetPerformanceCounter and use it (if it passes tests)
    • [ ] 10 for FIX_LINUX __debugbreak: need to create one place with debugbreak for all platforms/archs
    • [ ] 02 for FIX_LINUX GetWindowRect: I used SDL functions for Linux part, but it did not work well in Windows (why?)
    • [ ] 08 for FIX_LINUX ddraw.h and amstream.h: It need only for play avi into and other videos. Will require to use ffmpeg or something like that
    • [ ] 01 for FIX_LINUX ExitProcess: I used "exit(0)" for Linux port, but it is part of SailorsEditor, which should be moved from engine IMHO.
    • [ ] 02 for FIX_LINUX SHGetKnownFolderPath: I used SDL_GetPrefPath for Linux port. Should I keep SHGetKnownFolderPath for compatibility?
    • [ ] 02 for FIX_LINUX 7za.exe: one direct call to 7za.exe
    • [ ] 01 for FIX_LINUX CreateEventA: not sure if I need to prevent multiple instances of game
    • [ ] 03 for FIX_LINUX Beep: I'm fine if my pc speaker will not beep when I'm playng game)
    • [ ] 17 for FIX_LINUX s_debug.h: part for debugging user mods in compiler.cpp and s_dbg_*
  • Ship icon instead of Sea on world map

    Ship icon instead of Sea on world map

    Hello. I noticed, that in original COAS code textures for World Map Actions are confused. Exit to ship has sea icon's number and Exit to sea has ship icon's number. And I have bug on latest engine version. I always see Ship icon on world map instead of Sea icon. I tested it alot, and by logging WM_UpdateCurrentAction method I find that when we see sea icon, game logs out 1 in string sti(worldMap.encounter_type), but 1 means ShipEnc. And I find 3 ways to fix it: first one is changing 235 and 223 strings in file wdm_player_ship.cpp. I've replaced -1 by 0. The second one is adding Log_info in WM_UpdateCurrentAction method. And the last one is adding Log_info in WM_SetPossibleCommands method and pressing Enter once I on world map. Also, I find doubtful code in BI_MSG_REFRESH: if (m_pShipIcon) m_pShipIcon->SetUpdate(); It seems like bad way to fix Ship icon on world map.

    To Reproduce Just change icons number to normal in WM_InitializeCommands method. Normal numeration u can see in /Textures/BATTLE_INTERFACE/WorldMapCommands.tga.tx.

    Expected behavior Fix this problem by replacing -1 by 0 in engine scripts that I described. Also game developers should change texture numbers in scripts. Ship is 4 12 and Sea is 1 9. Screenshots https://drive.google.com/file/d/1V-2snzaKKnyuelkuzuybK9Gd9m-Ee0QT/view?usp=sharing https://drive.google.com/file/d/1UOjUk0rjMJzwLFDfBRg_axS7b4-3asUW/view?usp=sharing

  • ShipMan::SetAnimation

    ShipMan::SetAnimation

    Sentry Issue: STORM-ENGINE-B8

    EXCEPTION_ACCESS_VIOLATION_READ: Fatal Error: EXCEPTION_ACCESS_VIOLATION_READ
      File "Sailors.cpp", line 458, in ShipMan::SetAnimation
      File "Sailors.cpp", line 1100, in Sailors::Realize
      File "Core.cpp", line 555, in CORE::ProcessRealize
      File "Core.cpp", line 186, in CORE::Run
      File "Main.cpp", line 31, in `anonymous namespace'::RunFrame
    ...
    (6 additional frame(s) were not displayed)
    
An SDL-1.2 compatibility layer that uses SDL 2.0 behind the scenes.

Simple DirectMedia Layer (SDL) sdl12-compat --- https://www.libsdl.org/ This is t

Jun 8, 2022
Improved version of the X-Ray Engine, the game engine used in the world-famous S.T.A.L.K.E.R. game series by GSC Game World.
Improved version of the X-Ray Engine, the game engine used in the world-famous S.T.A.L.K.E.R. game series by GSC Game World.

OpenXRay OpenXRay is an improved version of the X-Ray Engine, the game engine used in the world-famous S.T.A.L.K.E.R. game series by GSC Game World. S

Jun 18, 2022
CLUSEK-RT is a complex game engine written in C++ and the successor of the CLUSEK game engine
CLUSEK-RT is a complex game engine written in C++ and the successor of the CLUSEK game engine

CLUSEK-RT is a complex game engine written in C++ and the successor of the CLUSEK game engine. This engine has been designed with a cross-platform design in mind. Thanks to Vulkan API it delivers a next-gen experience with ray tracing to both Linux and Windows platforms

Jun 12, 2022
This is a list of different open-source video games and commercial video games open-source remakes.

This is a list of different open-source video games and commercial video games open-source remakes.

Jun 20, 2022
Ground Engine is an easy to use Game Engine for 3D Game Development written in C++
Ground Engine is an easy to use Game Engine for 3D Game Development written in C++

Ground Engine is an easy to use Game Engine Framework for 3D Game Development written in C++. It's currently under development and its creation will b

Jun 10, 2022
Open-source, cross-platform, C++ game engine for creating 2D/3D games.

GamePlay v3.0.0 GamePlay is an open-source, cross-platform, C++ game framework/engine for creating 2D/3D mobile and desktop games. Website Wiki API De

Jun 17, 2022
The Atomic Game Engine is a multi-platform 2D and 3D engine with a consistent API in C++, C#, JavaScript, and TypeScript
The Atomic Game Engine is a multi-platform 2D and 3D engine with a consistent API in C++, C#, JavaScript, and TypeScript

The Atomic Game Engine is a multi-platform 2D and 3D engine with a consistent API in C++, C#, JavaScript, and TypeScript

Jun 19, 2022
OGRE is a scene-oriented, flexible 3D engine written in C++ designed to make it easier and more intuitive for developers to produce games and demos utilising 3D hardware.
OGRE  is a scene-oriented, flexible 3D engine written in C++ designed to make it easier and more intuitive for developers to produce games and demos utilising 3D hardware.

OGRE (Object-Oriented Graphics Rendering Engine) is a scene-oriented, flexible 3D engine written in C++ designed to make it easier and more intuitive for developers to produce games and demos utilising 3D hardware. The class library abstracts all the details of using the underlying system libraries like Direct3D and OpenGL and provides an interface based on world objects and other intuitive classes.

Jun 20, 2022
Godot Engine – Multi-platform 2D and 3D game engine
Godot Engine – Multi-platform 2D and 3D game engine

Godot Engine 2D and 3D cross-platform game engine Godot Engine is a feature-packed, cross-platform game engine to create 2D and 3D games from a unifie

Jun 22, 2022
Project DELTA - An open-source trainer built on the Void Engine for Toby Fox's games and their spin-offs.

Project DELTA v3 Project DELTA - An open-source, modular mod menu for Toby Fox's games and their spin-offs. Important note to Grossley: Yes, it is out

Apr 20, 2022
An Unreal Engine 4 silent aim method, not usable on all games. Tested on Fortnite, Rogue Company, Bloodhunt, and Splitgate.

UE4-Silent-Aim An Unreal Engine 4 silent aim method, not usable on all games. Only tested on Fortnite, Rogue Company, Bloodhunt, and Splitgate. Done t

May 31, 2022
This is netvars, interfaces and class ids dump from Valve's Source2 Engine games

About this This is netvars, interfaces and class ids dump from Valve's Source2 Engine games: Artifact Classic Artifact Foundry Dota 2 Dota Underlords

May 24, 2022
Flax Engine – multi-platform 3D game engine
Flax Engine – multi-platform 3D game engine

Flax Engine – multi-platform 3D game engine

Jun 20, 2022
MAZE (My AmaZing Engine) - 🎮 Personal open-source cross-platform game engine
MAZE (My AmaZing Engine)  - 🎮 Personal open-source cross-platform game engine

MAZE (My AmaZing Engine) is the self-written open-source cross-platform game engine in the active development stage. At the moment it is my main pet project, developed for the purpose of learning and preserving different game dev technologies.

Jan 9, 2022
Rogy-Engine- - My 3D game engine source code.
Rogy-Engine- - My 3D game engine source code.

Rogy-Engine Development My 3D game engine. (NOT THE FINAL VERSION- Windows only) Features: PBR shading and reflection probes with parallax correction.

Apr 29, 2022
Hyperion Engine is a 3D game engine written in C++
Hyperion Engine is a 3D game engine written in C++

Hyperion Engine About Hyperion Engine is a 3D game engine written in C++. We aim to make Hyperion be easy to understand and use, while still enabling

Jun 18, 2022
Minetest is an open source voxel game engine with easy modding and game creation

Minetest is an open source voxel game engine with easy modding and game creation

Jun 22, 2022
Bounce is a 3D physics engine for games.

Bounce Welcome! Bounce is a 3D physics engine for games. Features Common Efficient data structures with no use of STL Fast memory allocators Built-in

Jun 5, 2022
Speedrun plugin for Source engine games.

Features Automatic demo recording Accurate session timing Speedrun timer with complex custom rule system Tools for segmented and tool-assisted speedru

Jun 19, 2022