Skip to content

Gaming32/kilo-engine

Repository files navigation

kilo-engine

A Simple 3D Game Engine

Installation

Warning: snpashot versions are a subject to constant, breaking changes, without a version number change. For that reason, a dependency refresh might break your code if you use a snapshot version of the engine. It is recommended to users of snapshot versions (currently there are no public release versions) to keep track of this README page and this respository's commit history.

Gradle Kotlin
// build.gradle.kts

repositories {
    mavenCentral()
    maven("https://maven.jemnetworks.com/releases")
    maven("https://maven.jemnetworks.com/snapshots")
    maven("https://maven.quiltmc.org/repository/release")
    maven("https://jitpack.io")
}

dependencies {
    implementation("io.github.gaming32:kilo-engine:0.1-SNAPSHOT")
}
Gradle Groovy
// build.gradle

repositories {
    mavenCentral()
    maven { url = "https://maven.jemnetworks.com/releases" }
    maven { url = "https://maven.jemnetworks.com/snapshots" }
    maven { url = "https://maven.quiltmc.org/repository/release" }
    maven { url = "https://jitpack.io" }
}

dependencies {
    implementation "io.github.gaming32:kilo-engine:0.1-SNAPSHOT"
}
Maven
<!-- pom.xml -->

<repositories>
  <repository>
    <id>gaming32</id>
    <name>Gaming32</name>
    <url>https://maven.jemnetworks.com/releases</url>
  </repository>
  <repository>
    <id>gaming32-snapshots</id>
    <name>Gaming32 Snapshots</name>
    <url>https://maven.jemnetworks.com/snapshots</url>
  </repository>
  <repository>
    <id>quiltmc</id>
    <name>QuiltMC</name>
    <url>https://maven.quiltmc.org/repository/release</url>
  </repository>
  <repository>
    <id>jitpack.io</id>
    <name>Jitpack</name>
    <url>https://jitpack.io</url>
  </repository>
</repositories>

<dependencies>
  <dependency>
    <groupId>io.github.gaming32</groupId>
    <artifactId>kilo-engine</artifactId>
    <version>0.1-SNAPSHOT</version>
  </dependency>
</dependencies>

Basic example

Kotlin
fun main() = object : KiloEngineGame {
    init {
        Resources.resourceGetter += javaClass::getResourceAsStream
    }

    override val title get() = "My Game"

    override fun loadInitScene() {
        sceneLoader.loadScene("/my_game/my_scene.scene.json5", scene)
    }
}.main()
Java
public class MyGame extends KiloEngineGame {
    public static void main(String[] args) {
        Resources.addResourceGetter(MyGame.class::getResourceAsStream);
        new MyGame().main();
    }

    @Override
    @NotNull
    public String getTitle() {
        return "My Game";
    }

    @Override
    public void loadInitScene() {
        getSceneLoader().loadScene("/my_game/my_scene.scene.json5", getScene());
    }
}

Scenes

A game in Kilo Engine is made up of "scenes" (well actually just one at this point). A scene is a collection of entities that make up the game, as well as various other minor things.

Scenes can be constructed purely through using code, but it is preferred to specify the initial data of scenes through .scene.json5 files. You can load scenes from Json5 files using sceneLoader#loadScene.

Scene Json5 syntax is simple. Here's a brief example:

Sample Json5 scene
{
  entities: [
    // What's a level without some entities, eh?
    // More details on entity Json5 syntax below in the "Entities" section.
    {
      kinematic: true,
      components: [
        {
          type: "mesh",
          mesh: "/example/example.obj"
        },
        "meshRenderer",
        {
          type: "meshCollider",
          collision: {
            Brick_Antique_01: "wall",
            Brick_Basket: "floor",
            Death_Plane: "death"
          }
        }
      ]
    },
    {
      position: [0, 1.4, -5],
      components: [
        {
          type: "capsuleCollider",
          radius: 0.4,
          length: 1
        },
        "player",
        {
          type: "camera",
          offset: [0, 0.7, 0],
          skybox: { // A cubemap skybox
            base: "/example/skybox", // *Optional* base path for the paths in this object
            down: "down.png", // Because `base` is specified, this will load from `/example/skybox/down.png`.
            up: "up.png",
            negativeZ: "negativeZ.png",
            positiveZ: "positiveZ.png",
            negativeX: "negativeX.png",
            positiveX: "positiveX.png"
          },
          skybox: [0.75, 0.25, 0.25], // A light red solid color skybox
        }
      ]
    }
  ]
}

So you want to see how this is done in code? Well here you go:

The above example, but in Kotlin
Entity(scene, DVector3()).apply {
    body.setKinematic()
    val model = MeshComponent(this, sceneLoader.loadObj("/example/example.obj")).model
    MeshRendererComponent(this)
    MeshColliderComponent(this, CollisionModel(model, mapOf(
        model.materials["Brick_Antique_01"]!! to CollisionTypes.WALL,
        model.materials["Brick_Basket"]!! to CollisionTypes.FLOOR,
        model.materials["Death_Plane"]!! to CollisionTypes.DEATH
    )))
}
Entity(scene, DVector3(0.0, 1.4, -5.0)).apply {
    CapsuleColliderComponent(this, 0.4, 1.0)
    PlayerComponent(this, Vector2f())
    CameraComponent(
        this, 
        offset = DVector3(0.0, 0.7, 0.0),
        skybox = Skybox.Cubemap.relative(
            "/example/skybox",
            "down.png",
            "up.png",
            "negativeZ.png",
            "positiveZ.png",
            "negativeX.png",
            "positiveX.png"
        )
        // skybox = Skybox.SolidColor(0.75f, 0.25f, 0.25f)
    )
}
The above example, but in Java
final Scene scene = getScene();

final Entity levelMesh = new Entity(scene, new DVector3());
levelMesh.getBody().setKinematic();
final Model model = new MeshComponent(
    levelMesh, getSceneLoader().loadObj("/example/example.obj")
).getModel();
new MeshRendererComponent(levelMesh);
new MeshColliderComponent(levelMesh, new CollisionModel(model, Map.of(
    model.getMaterials().get("Brick_Antique_01"), CollisionTypes.WALL,
    model.getMaterials().get("Brick_Basket"), CollisionTypes.FLOOR,
    model.getMaterials().get("Death_Plane"), CollisionTypes.DEATH
)));

final Entity player = new Entity(scene, new DVector3(0, 1.4, -5));
new CapsuleColliderComponent(player, 0.4, 1);
new PlayerComponent(player, new Vector2f());
new CameraComponent(
    player, 
    new DVector3(0.0, 0.7, 0.0),
    Skybox.Cubemap.relative(
        "/example/skybox",
        "down.png",
        "up.png",
        "negativeZ.png",
        "positiveZ.png",
        "negativeX.png",
        "positiveX.png"
    )
    // new Skybox.SolidColor(0.75f, 0.25f, 0.25f)
);

About

Simple 3D game engine

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published