Giter Site home page Giter Site logo

godot-mdk's Introduction

Open source reimplementation of MDK in Godot

This project aims to reimplement MDK using Godot Engine. It is not in a playable state yet.

This is being developed as a personal project for several reasons:

  • Allow MDK to run on modern systems easily, on any platform. No compatibility wrappers needed.
  • Enhance the game in ways that were not possible beforehand: uncapped framerate, replayability options, quality of life features, …
  • Give me another "real world" Godot project to work on πŸ™‚

Help is needed for reverse engineering file formats! This reverse engineering effort is required to make the game playable. If you have experience with reverse engineering (especially 3D file formats), feel free to chime in the GitHub issue tracker.


Running the project

This project is currently being developed with Godot 3.4beta4, but it should open fine in 3.3.3 too.

Running the project requires game data from a MDK installation. You can buy the original game on GOG or Steam. Waiting for a sale? Set up an email alert using IsThereAnyIdeal.

godot-mdk will automatically detect the GOG installation folder if it's installed at the default location (on both Windows and Linux when installed using WINE). Auto-detection of the Steam folder hasn't been implemented yet. Alternatively, you can copy the MDK data files to a folder called mdk or MDK within this project folder.

Several file formats from the game have been reverse engineered for interoperability purposes. This allows the game to run without having to convert game data manually (and without redistributing it within this repository).

The project currently does not require game data from MDK to be opened in the editor, but this may change in the future (at least for level scenes).

License

Copyright Β© 2021 Hugo Locurcio and contributors

Unless otherwise specified, files in this repository are licensed under the MIT license. See LICENSE.md for more information.

This repository does not include any proprietary game data from MDK.

This project is not affiliated with Shiny Entertainment or Interplay Inc.

godot-mdk's People

Contributors

calinou avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

godot-mdk's Issues

Implement level bosses

Related to #11.

Most levels have a boss at the end that has its own logic. This needs to be implemented to allow the game to be completed as intended.

Killing the boss in those levels generally starts the end-of-level sequence a few seconds later.

Load FLIC animated image file format

Related to #6 and #8.

Not critical for a working game, but having this working would make the main menu look nicer and closer to the original. The FLIC file format is similar to how many GIFs are stored, with the format storing differences between frames rather than full frames themselves. This format is documented and has many open source implementations available.

  • MISC/FLIC/MDK12.FLC: Main menu animation (Kurt landing on MDK logo)
    • FLC animation, 600x360x8, 82 frames, 33ms per frame
    • No associated sound.
  • MISC/FLIC/MDKEND.FLC: Kurt & Bones escape end sequence
    • FLC animation, 600x360x8, 316 frames, 33ms per frame
    • Sound is played back at the same time from a different resource file.

A FLIC loader should be implemented to load and display those images. A GDScript solution is preferable, but GDNative or a custom C++ module is acceptable too.

godot-gdgifexporter may be used as inspiration for this. However, remember that we need to load FLIC animations, not save them πŸ™‚

Note: From what I've read, only the GOG version has the MDKEND.FLC cutscene, not the Steam version.

Reverse engineer 3D model data

MDK uses 3D model data for many purposes:

  • Enemies
  • The player during the flying intro and outro sequences (but not during the rest)
  • Pick-up items
  • Sniper projectiles

This data should then be used to generate a Mesh resource using one of Godot's procedural geometry generation classes. The Mesh resource can then be displayed using a MeshInstance node. The texture can then be displayed by adding a SpatialMaterial to this MeshInstance node.

Model animation will need to be displayed somehow. MDK likely uses vertex animations instead of skeletal animation, but I cannot confirm this for sure yet. If vertex animation is used, it can be displayed either by using ImmediateGeometry (which is slow) or by using a vertex shader (which is difficult). If skeletal animation is used, it can be displayed using Godot's usual skeleton node setup which can be created and manipulated at run-time.

Cache data loaded from MDK data files for faster loading

Since MDK's data files are loaded and their contents interpreted in GDScript, this is a slow operation done on every startup. This in turn impacts iteration times when working on the project using the Godot editor. We can make this startup cost only happen once by caching this data to user://.

Since the MDK data never changes, this cache should be active both when running from the editor and in exported builds. There should be a --no-mdk-cache command line argument to disable this cache if needed.

Ideally, the cache generation process should display a progress bar, but displaying a static "Caching MDK game data, this may take a while…" label is acceptable too.

Load GIF file format for main menu slideshow

Related to #7 and #6.

When the player is inactive on the main menu for a certain amount of time (~30 seconds), MDK displays a slideshow of several static GIF images:

  • MISC/MDKS_001.GIF
  • MISC/MDKS_002.GIF
  • MISC/MDKS_003.GIF
  • MISC/MDKS_004.GIF
  • MISC/MDKS_005.GIF
  • MISC/MDKS_006.GIF
  • MISC/MDKS_007.GIF
  • MISC/MDKS_008.GIF

A GIF loader should be implemented to load and display those images. A GDScript solution is preferable, but GDNative or a custom C++ module is acceptable too.

Some sounds aren't loaded correctly

Sounds such as OPTBUTT and SNDTEST play back fine, but several sounds such as OPTSONG are garbled and very loud. This may be an issue with Godot itself – see comments in godotengine/godot-proposals#732.

The sounds are loaded into AudioStreamSample resources using a script inspired by https://github.com/Gianclgar/GDScriptAudioImport.

To test this, change the sound identifier played here then click a button in the main menu:

Sound.play(self, MDKData.audio_samples["OPTBUTT"])

Make sure to turn down your volume before, especially if using headphones πŸ™‚

Implement enemy spawners/generators

Related to #11.

Enemy spawners should be implemented. Here's how they seem to work in the original game:

  • The spawner is made active once the player gets close enough.
  • It spawns an enemy of a given type every so often (the delay needs to be measured). It plays a "spitting out" animation while doing so.
    • There is likely a maximum number of alive enemies per spawner too; measure it.
  • Dealing damage to the spawner will eventually destroy the spawner.

Implement enemy AI

Related to #10.

The game has many different enemies, but there is likely common AI logic that needs to be implemented.

  • Physics.
  • Animation playback.
  • Moving towards the player and shooting.
    • Measure if shooting happens more frequently when an enemy is up close.
  • Taking damage and dying.

Implement the player's sniper mode

Related to #4.

The sniper mode (accessed by right-clicking) needs to be implemented. It's required at several points to progress throughout the game, especially for bosses.

Automatically detect the Steam game data folder

Like we already do for GOG, we should detect the Steam installation folder as an alternative. GOG should be picked first if both paths are available, as the GOG version includes cutscenes that the Steam version doesn't.

I don't have access to MDK's Steam version, so help is welcome here.

Reverse engineer level data

Related to #1.

To play the game, we need to figure out how to load levels and their textures from the original MDK data files. From what I've seen, levels are loaded using some kind of chunk system, but we can probably load everything at once on today's hardware (at least as an initial implementation).

I don't know how gameplay triggers were stored (in the level files or in the executable). Gameplay triggers will need to be ported somehow, likely by creating Area nodes at run-time that are connected to functions implemented in GDScript.

Gameplay triggers are quite varied, and many of them are only used in a single level. Some examples:

  • Display a message at the center to the screen.
  • Open/close a door.
  • Start a different music track.
  • End the level.
    • In some levels, this happens after a boss was killed instead.

Load Interplay MVE file format

Related to #7 and #8.

Very low-priority. This is used to display the video ending sequence MISC/FLIC/MDKBZK.MVE with audio playback. This will likely require GDNative-based video playback such as godot-videodecoder. Once this decoder is implemented, a VideoPlayer node can be used to handle the rest.

Interplay MVE Movie
Stream #0:0: Video: interplayvideo, pal8, 432x320, 14.99 fps, 14.99 tbr, 1000k tbn, 1000k tbc
Stream #0:1: Audio: interplay_dpcm, 22050 Hz, stereo, s16, 352 kb/s

Reverse engineer animated sprite data (player sprite)

While not in the intro and outro "flying" sequences, the player is rendered as an animated 2D sprite.

This data needs to be reverse engineered and loaded into an AnimatedSprite3D node. This way, Kurt can be displayed in all his glory πŸ™‚

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.