Giter Club home page Giter Club logo

planetkit's Introduction

PlanetKit

Travis CI build status AppVeyor build status

Colorful blobs that might one day resemble planets.

Requires the latest stable version of Rust.

Screenshot

Goals

  • Build an easily-hackable toolkit for building games based around voxel globes. The simple case should be simple, and the migration path to greater customisation should be smooth.

  • Document everything. Both the API and implementation should aim to teach. I'm also blogging as I go.

  • Be open and welcoming. If you have a question, a suggestion, an idea, or just want to say "hi", please feel free to open an issue.

Non-goals

  • Build a game engine. I'm going to end up doing this accidentally. But my preference is to use existing libraries where they exist, and contribute to them where it makes sense.

  • Expose a stable API. I do value stability, but PlanetKit is too young and exploratory to be thinking about that just yet. If you use it for something, I'll help you deal with breakage.

  • Meet everyone's needs. I intend to focus on a very narrow set of game styles. But "narrow" is hard to define clearly. If you're not sure whether our visions are aligned, please open an issue!

License

PlanetKit is primarily distributed under the terms of both the MIT license and the Apache License (Version 2.0).

See LICENSE-APACHE and LICENSE-MIT for details.

planetkit's People

Contributors

atk avatar jeffparsons avatar legneato avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

planetkit's Issues

README.md needs a "Contributing" section

Needs guidelines like...

  • For anything that's not trivial or a bug fix, please open an issue to discuss first.
  • Please try to make the smallest practical change.

And an "if you want to make me/us super-happy" section with stuff like...

  • Run rustfmt
  • Run clippy

ArchLinux

This seems to be similar to issue 3. Manjaro is Arch based. I'm using vanilla Arch. Below is a stack trace. I just installed the latest bleeding edge version of X.Org (in case you don't know Arch is always bleeding edge with everything). This makes it a good distro for edge case testing.

pk_version: 0.0.1
  Feb 27 09:13:04.630 INFO Creating main window
thread 'main' panicked at 'Failed to get root window: XError { description: "GLXBadFBConfig", error_code: 181, request_code: 156, minor_code: 34 }', /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/src/libcore/result.rs:870
stack backtrace:
   1:     0x5580a9a190ac - std::sys::imp::backtrace::tracing::imp::write::h9c41d2f69e5caabf
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/src/libstd/sys/unix/backtrace/tracing/gcc_s.rs:42
   2:     0x5580a9a1c18e - std::panicking::default_hook::{{closure}}::hcc803c8663cda123
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/src/libstd/panicking.rs:351
   3:     0x5580a9a1bd94 - std::panicking::default_hook::hd5bda4e453dfb4be
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/src/libstd/panicking.rs:367
   4:     0x5580a9a1c62b - std::panicking::rust_panic_with_hook::hffbc74969c7b5d87
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/src/libstd/panicking.rs:555
   5:     0x5580a9a1c4c4 - std::panicking::begin_panic::hc4c5d184a1e3fb7c
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/src/libstd/panicking.rs:517
   6:     0x5580a9a1c3e9 - std::panicking::begin_panic_fmt::h34f5b320b0f94559
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/src/libstd/panicking.rs:501
   7:     0x5580a9a1c377 - rust_begin_unwind
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/src/libstd/panicking.rs:477
   8:     0x5580a9a46f8d - core::panicking::panic_fmt::h1016b85b51d1931f
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/src/libcore/panicking.rs:69
   9:     0x5580a99cdc18 - core::result::unwrap_failed::h8ca805782c93f1bc
  10:     0x5580a99d7fb3 - winit::api::x11::window::Window::new::he8df02577c6ca97d
  11:     0x5580a99d9a8a - winit::window::<impl winit::WindowBuilder>::build::hcc6aea1f81154d5a
  12:     0x5580a998d5f4 - glutin::platform::platform::x11::Window::new::h66d806b0c722ddb9
  13:     0x5580a99926be - glutin::window::<impl glutin::WindowBuilder<'a>>::build::h64aaa44c6f441a13
  14:     0x5580a996eca3 - glutin_window::GlutinWindow::new::h2cf3425256314d66
  15:     0x5580a9970978 - <glutin_window::GlutinWindow as window::BuildFromWindowSettings>::build_from_window_settings::h2e83e6407a359fb5
  16:     0x5580a993cca5 - planetkit::window::make_window::h9a7eb91ef4a7a164
  17:     0x5580a9942079 - planetkit::simple::new::h77804dc5a762dfa4
  18:     0x5580a98e96e6 - demo::main::h00e78e1ecf38f050
  19:     0x5580a9a234ea - __rust_maybe_catch_panic
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/src/libpanic_unwind/lib.rs:98
  20:     0x5580a9a1cd96 - std::rt::lang_start::ha0568cc91d8c5b09
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/src/libstd/panicking.rs:436
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/src/libstd/panic.rs:361
                        at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/src/libstd/rt.rs:57
  21:     0x7fe5c70f6290 - __libc_start_main
  22:     0x5580a98e0c79 - _start
  23:                0x0 - <unknown>

Separate nphysics world per globe

At the moment I have a single global nphysics world:

/// `World`-global resource for nphysics `World`.
pub struct WorldResource {
    pub world: World<Real>,
}

But all coordinates given to nphysics are globe-local, because (as far as I know?) nphysics doesn't use any kind of hierarchical coordinate system. (Trying to use some kind of universal coordinates in a solar system would result in huge uselessly-imprecise numbers being thrown at nphysics.)

Things on different globes aren't going to interact with each other, so we're better off having a separate nphysics world per globe so we can keep using globe-local coordinates.

planetkit panics

Planetkit panicked at my machine (commit 17df8a..):

uname -srvo  
Linux 4.8.14-1-MANJARO #1 SMP PREEMPT Sat Dec 10 23:58:26 UTC 2016 GNU/Linux
cargo run              
    Finished debug [unoptimized + debuginfo] target(s) in 0.2 secs
     Running `target/debug/main`
pk_version: 0.0.1
  Dec 24 19:13:20.876 INFO Creating main window
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: "Couldn\'t find any pixel format that matches the criterias."', /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/src/libcore/result.rs:837

I may provide a stacktrace if necessary.

Kaboom initial kinda-playable release

This is not the "a real game you'd want to play" release, but rather the very first release where it's technically possible to play and tell who is winning.

Mandatory:

  • A simple projectile weapon that explodes on a timer. (Easier initially than colliding with terrain.)
  • Recognise explosion near a player (same radius as explosion)
    • Give points to player who fired the projectile
    • Log message about the kill
    • Re-spawn the victim (initially just move the entity rather than re-creating it)
  • Communicate about grenades, explosions, etc., over the network

Desirable for a release soon after:

  • Explosion effect (just a temporary yellow sphere)
  • Blow up terrain around the explosion
    • Convert real space coordinates to grid space
  • Smooth chase cam to paper over the awful blocky movement of CellDwellers.
  • Dumb bots that just walk around waiting to die.

Explicitly out-of-scope:

  • Non-grid based movement (I'm not touching this until the ECS-friendly nphysics release)
  • Any kind of HUD. Log messages to know what's going on only

How to make a new world and render it?

I want to create a globe and render it. Here's a start:

extern crate planetkit as pk;
use pk::globe::*;
use pk::camera::*;
use pk::cell_dweller::AutoResource;

fn main() {

    let mut app = pk::AppBuilder::new()
        .build_gui();
    {
        let world = app.world_mut();
        let globe = Globe::new_earth_scale_example();
        world.create_entity().with(globe);
        let cam = DefaultCamera::new(world);
        world.add_resource(cam);
    }

    app.run();
}

I didn't expect it to work. What do I have to do next to render the world?

Hi!

First off, thanks for all the code and well written blog posts! I love these hexagonal planets, and I'm not geometrically-minded enough to have ever come up with this.

A friend of mine (3D artist), and I are working on a game together, just for fun. I've been using your code as a base. It's going to be a 3D version of a 2D game we made several years back (also just for fun). Here's the premise:

Cross between third person shooter and RTS. Networked multiplayer. Each player has a hero which he controls using WASD and mouse to aim. You can build buildings, and from there construct minions. For now we want to keep it simple with just 2 unit types - miners and fighters. Planets will have some natural resources that you need to mine to build more structures and minions. You can press left ctrl to disable mouse aiming so that you can select and command your units/structures. Conquer the solar system!

So far all I've done is made a third person camera and got the player to rotate smoothly while still maintaining the cell-based turning/movement that you have set up. I think for smooth movement, I will interpolate position between cells. Movement is slightly awkward with smooth rotations, because you walk to the cell that you are "most rotated towards", so it can feel a little strafe-y if you are not facing directly toward the cell you will move to. But I think it feels fine enough.

Check out a video of what I have so far

Anyway, I'd love to collaborate, even if only just to help myself stay up-to-date with your progress on this.

Replace `copy_all_authoritative_cells` with proper solution

Chunks share some cells with their neighbors, but only one of the chunks is the source of truth. There are occasions when we want to copy the authoritative cells into chunks that merely have a copy of those cells.

This is currently achieved through the atrocious function Globe::copy_all_authoritative_cells, which loops over all loaded chunks and checks whether any of them can be given more current data from their adjacent loaded chunks. This gets quadratically slower the more chunks you have loaded. (Eww.) This currently happens when

  • a new chunk is loaded; it might need to be copied to and/or from; and
  • a chunk is updated by mining (removing a block).

It is pretty clear to me that neither of these cases needs to blindly loop over all chunks, so copy_all_authoritative_cells should probably not exist at all.

What do we have to work with?

Now, this is pretty easily solved for the case of needing to copy updates into a given known chunk. Each loaded chunk already stores a list of its neighbouring chunks (whether they are loaded or not), including:

  • The neighboring chunk's origin
  • The last known version (serial number) of the neighboring chunk's content, so we know whether we need to copy updates or not; and
  • A list of cells belonging to that neighbor, but specified in this chunk's root.

What's missing?

The above is all well and good when you know what chunk(s) you're needing to copy values into, but a lot of the time you will only know what chunks you need to copy from. Consider, for example, the mining system. Whenever you remove a block, you know you just made the update in the chunk that owns that block, and now you need to update any other chunks that share it. So you know where you're copying from, but not where you're copying to.

Proposed solution

Extend the idea of Chunk::authoritative_neighbors used for copying cells from neighboring chunks, such that chunks also carry information about neighboring chunks and cells that they need to copy data into, say, Chunk::subordinate_neighbors. (That name sucks, but so does authoritative_neighbors. Feel free to bikeshed both!).

This is a tad harder than populating Chunk::authoritative_neighbors, but I believe it can be achieved through the use of the Neighbors iterator, and looking at which of those cells is owned by the main chunk we're considering. This will make chunk initialisation itself a little slower on account of the extra work, but it will drastically improve everything else across the board, and we can optimise that small bit later.

Split up and rename `CellPos` and friends

I'm planning a bit of a clean-up/refactor of what is currently in the globe module. The first part will be to move everything that relates purely to our Discrete Global Grid out into a separate top-level grid module, and then split up and rename a few of the structures. The second step will be a similar clean-up of everything to do with the voxmap, chunks, etc.

For clarity, what's in for this first step:

  • CellPos
  • Dir
  • PosInOwningRoot
  • Root
  • (RootResolution, which doesn't yet exist, but I'll use as a synonym for [IntCoord; 2])
  • Any functions that deal with these types.

The refactor bit will be to split CellPos into 2-dimenstional and 3-dimensional variants, because often I only deal with a "column" on the grid rather than a point in 3D grid space. I dismissed this earlier ("why not just ignore the z-axis?"), but I'm increasingly finding that I'd like the clarity about that encoded at the type level.

So... here comes the hard bit that I'd like input on: naming. I'm currently leaning towards (in roughly the same order as above):

  • GridPt2
  • GridPt3
  • Dir
  • (TODO: think about PosInOwningRoot; that can follow from whatever we decide for the rest)
  • Root
  • RootResolution

But I have a few questions in mind that might push me toward different naming:

  • Should I avoid abbreviations, like Nalgebra now does with its Point2 etc.? That would mean names like GridPoint2.
  • Should I just call it Point2, and rely on name-spacing to disambiguate it from the other Point2 (real coordinates, from Nalgebra) used in PlanetKit? That sounds like a recipe for confusion to me.
  • If I keep the Grid prefix on GridPoint2, should I add it to everything (e.g. GridDir) for consistency? Or would that be Emerson's "foolish consistency"? 😅
  • Should I not qualify RootResolution, and just call it Resolution instead? It's only qualified now because there's a type in the globe module for chunk resolution, but maybe only that (less frequently used) type really needs its name qualified like that.

Any and all thoughts on these questions would be much appreciated! 😄 ❤️

Exploring alignment with Evoli

Hi Jeff!

While our mutual projects might be on ice at the moment, there’s some fun possibilities for collaboration or cross-pollination in the future should the wheels start turning again. I designed a showcase game for Amethyst called Evoli:

https://github.com/amethyst/evoli

The longer term plan was always that we’d want to move to a globe-based playground. There’s no call-to-action for now, but I hope we might chat more in the future :)

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.