ggez / ggez Goto Github PK
View Code? Open in Web Editor NEWRust library to create a Good Game Easily
Home Page: http://ggez.rs
License: MIT License
Rust library to create a Good Game Easily
Home Page: http://ggez.rs
License: MIT License
Especially for font rendering.
Now, the obvious way is to check the image size in Image::make_raw()
and if necessary create a larger buffer and blit the image into it, leaving the rest of it zero. That will work fine, BUT, now we suddenly need a UV in every image and make that work with the current UV'ing code.
ugh.
But the alternative is to make this a special case for Text
types, which will do exactly the same thing, which is not really any better. So, screw it, it should go in the Image
code, and each Image
will just acquire a default UV that is not necessarily {0, 0, 1, 1}
This has been reported to rustc and should be fixed soon, just want to keep track of it here: rust-lang/rust#41944
Namely, make it detect when you're running from cargo (CARGO_MANIFEST_DIR
) and look in the right location then as well. That would solve the problem that people have with the required resources
location sneakily moving about; it could always look in the cargo root dir and people could just look there.
Make sure it looks it up at runtime with std::env::vars()
instead of at compile-time with env!()
. That way someone building a game don't bake their build paths into something running on someone else's system.
It also starts getting to the point where it might make life easier to have a full abstract VFS tree instead of the sort of simple-and-stupid "look in place A, then look in place B, then look in place C..." system that we have now. Or at least generalizing that system.
They should be but there may be some sticky non-thread-safe context in the Context
object that prevents this. Find out for sure!
Pull request accepted, just needs to be released.
Hi, I tried running
cargo build --example astroblasto
And got the following error:
note: ld: library not found for -lSDL2_mixer
error: Could not compile `ggez`.
Tried running:
brew install sdl2
brew install sdl2_mixer --with-libvorbis
brew install sdl2_image
export LIBRARY_PATH="$LIBRARY_PATH:/usr/local/lib"
And got the example to work
Most of them are pretty easy, don't sweat the rest. Just go through looking for unimplemented!
.
Text stuff changed a fair bit, go through and clean it up and verify bitmap font stuff.
Got the following warning:
WARNING: Encountered error: ResourceNotFound("\'resources.zip\' file not found!)
when running:
cargo run --example astroblasto
Fixed by zipping and moved to target/debug/ folder
I'd like to chat with other people making and using this. Do you guys have any chat room links you could add to the readme or website?
It says
ggez is built on the latest stable Rust compiler and distributed on .
Is it meant to say
ggez is built on the latest stable Rust compiler and distributed on crates.io.
What it says on the tin.
At least on the Linux and Mac laptops I tried on, using an XBox 360 controller. Investigate more.
rodio sort of has a perfectly reasonable and logical structure that is also quite inconvenient to actually use.
Like, what on Linux or Mac runs at 130 fps instead runs at 6 fps.
Good example program: https://github.com/icefoxen/ggj2017 at least as of commit 851f83782d0e4dd05cb6633fd4a4e1ea9f2d1376
I blame SDL2. Still! Should get to the bottom of it one way or another.
Tested on:
It wouldn't be hard, but it might be extra bloat that nobody really uses. LOVE has a default font embedded, but LOVE also is a bit more of a runtime than ggez is, and has more sneaky global state than Rust usually likes. However, having a default font that's always available is often very nice for in-game debuggers...
The graphics::print()
and graphics::printf()
functions in LOVE just use the default font; right now we have those functions but they're marked as unimplemented.
Should happen eventually!
Hi, I tried to set text color using graphics::set_color
but it doesn't seem to work -- the text foreground is always white.
It plays for half a second, then sits around a while doing something ugly to out-of-bounds memory, then eventually crashes. Usually within 10-20 seconds, sometimes up to 150 on my laptop.
Ugh. Ugh ugh ugh. Kill it with fire and replace it with something else.
Should be easy, right?
Someday. I forget who was talking about this...
I did some experimentation and want to write down the results somewhere:
It's possible to use gfx from ggez but it requires enough re-architecting of things to be a significant headache. Creating SDL2's Renderer type consumes a Window, and creating creating a gfx window context also consumes the Window, and ggez is currently designed to require a Renderer. So you can't have both on the same window.
Getting them to interoperate would basically mean making a pluggable rendering backend for ggez, and between piston and gfx I feel like the Rust ecosystem has enough pluggable rendering backends.
Given a 1024x768 image, I would expect a program with window dimensions matching the image, which renders the image at Point::new(512., 384.)
, to look roughly identical to the source.
When I encountered this, my quick fix was to add a blank 128px to the top and bottom of the image to make it 1024x1024 (which resulted in no scaling).
I wrote this as an example, but wasn't sure if you'd want that as a PR or what since it's just for debugging the issue, so here's the source as a code block instead:
extern crate ggez;
use std::time::Duration;
use ggez::conf;
use ggez::event;
use ggez::{GameResult, Context};
use ggez::graphics;
use ggez::timer;
struct MainState {
image: graphics::Image,
}
impl MainState {
fn new(ctx: &mut Context) -> GameResult<MainState> {
ctx.print_resource_stats();
let image = graphics::Image::new(ctx, "checkers.jpg").unwrap();
let s = MainState { image: image };
Ok(s)
}
}
impl event::EventHandler for MainState {
fn update(&mut self, _ctx: &mut Context, _dt: Duration) -> GameResult<()> { Ok(()) }
fn draw(&mut self, ctx: &mut Context) -> GameResult<()> {
graphics::clear(ctx);
let dest_point = graphics::Point::new(512., 384.);
graphics::draw(ctx, &mut self.image, dest_point, 0.0)?;
graphics::present(ctx);
timer::sleep_until_next_frame(ctx, 60);
Ok(())
}
}
pub fn main() {
let mut c = conf::Conf::new();
c.window_width = 1024;
c.window_height = 768;
let ctx = &mut Context::load_from_conf("ratio-test", "ggez", c).unwrap();
let state = &mut MainState::new(ctx).unwrap();
if let Err(e) = event::run(ctx, state) {
println!("Error encountered: {}", e);
} else {
println!("Game exited cleanly.");
}
}
Basically the Travis build is failing because rust-sdl2 now depends on SDL2 2.0.4, while Travis only has 2.0.0 available. Can we find a backport or some such? Or just build it from scratch if necessary, though that sounds like a pain.
Distributions that include SDL2 2.0.4 include (see http://packages.ubuntu.com/search?keywords=libsdl2):
There IS an issue request for a source for SDL2 specifically to be added: travis-ci/apt-source-safelist#307
Seems to happen about 1/4 of the time on my laptop, very unreliable. Doesn't seem to happen when the window is not selected.
It's something weird happening in the timing code, but it's sort of weird.
Backtrace:
thread 'main' panicked at 'overflow when subtracting durations', ../src/libcore/option.rs:700
stack backtrace:
1: 0x55810edb0519 - std::sys::backtrace::tracing::imp::write::h00e948915d1e4c72
2: 0x55810edb3ebc - std::panicking::default_hook::_{{closure}}::h7b8a142818383fb8
3: 0x55810edb31b9 - std::panicking::default_hook::h41cf296f654245d7
4: 0x55810edb37f8 - std::panicking::rust_panic_with_hook::h4cbd7ca63ce1aee9
5: 0x55810edb3652 - std::panicking::begin_panic::h93672d0313d5e8e9
6: 0x55810edb35c0 - std::panicking::begin_panic_fmt::hd0daa02942245d81
7: 0x55810edb3541 - rust_begin_unwind
8: 0x55810edebc2f - core::panicking::panic_fmt::hbfc935564d134c1b
9: 0x55810edebca5 - core::option::expect_failed::h1d846c7a667396f7
10: 0x55810edae8bc - _<std..time..duration..Duration as core..ops..Sub>::sub::hedf4f5a7d9502bd0
11: 0x55810ed3ba9f - ggez::timer::sleep_until_next_frame::h0c06a01155e5f08e
at /home/icefox/src/ggez/src/timer.rs:177
12: 0x55810ecf5ea1 - _<astroblasto..MainState as ggez..game..GameState>::draw::h83e9d098d8960d6a
at /home/icefox/src/ggez/examples/astroblasto.rs:205
13: 0x55810eceff1e - _<ggez..game..Game<'a, S>>::run::hd5b398ab82fbc6f6
at /home/icefox/src/ggez/src/game.rs:188
14: 0x55810ecf6243 - astroblasto::main::h4882452e174ab6c4
at /home/icefox/src/ggez/examples/astroblasto.rs:247
15: 0x55810edbb9a6 - __rust_maybe_catch_panic
16: 0x55810edb2932 - std::rt::lang_start::h53bf99b0829cc03c
17: 0x55810ecf69b3 - main
18: 0x7fbe3d9f42b0 - __libc_start_main
19: 0x55810eced119 - _start
20: 0x0 - <unknown>
It seems inconsistent in tests, figure out what's up with that.
There's some updates to be made to the app_dirs crate itself which would make life nicer, see andybarron/app-dirs-rs#19
It seems to vary between next to the executable and above the executable between versions of rust-sdl2??? It's awful, either way.
See commit messages in 3dd760c
Incorporate the palette
crate?
Or at least make an easy way to use it. It's pretty awesome.
Because zip files have no idea of directories, they just store names, which may be paths.
We could fake it, but I'm not sure if it's a good idea or not.
Since love2d is our role model, why not make design our site to look a little bit like them? Certainly we can do better than the default Github generated site.
See what can be done to speed it up, since rusttype forces us to write our own renderer.
Apparently my system (and some others) already had it installed somewhere, but SDL2 mixer won't function without it.
We should provide a nice zip file of .dll's. Or just make everything pure Rust.
Coming from other frameworks, the methods for drawing stuff to the window might accept a graphic, position (x, y), and potentially some extended transform data (rotation, scale).
This time we have src
, and dst
(a pair of Option<Rect>
) and it's not immediately obvious to me what the intent is. Fumbling around, I managed to get a graphic in the center of the window by supplying None
as the src
and dst
by creating a Rect
with the appropriate x/y and width/height to match the image, effectively setting the bounding box for where the image should be drawn.
Really not sure how src
would be used, or if I'm even doing what would be expected for this simple case.
But this makes life horribly inconvenient sometimes so I don't want to do it just now.
Also it really shouldn't, but calling draw()
might require calling Image::set_color_mode()
or Image::set_blend_mode()
on something, which take mutable references. Another example of SDL being annoyingly stateful. Maybe we can abstract those out into parameters that get given to draw()
?
Deploying DLL's on Windows is a pain in the butt. Pure Rust is much easier to work with. This would mean essentially ditching SDL and using a collection of crates that provide the same functionalities.
Ditching SDL will make life harder on iOS and Android. Hmmm.
The things that we would need to replace:
cpal
does not! Does it work well enough? rodio
is built atop it, zang.The main concerns with this is that a) we don't want to depend on something that subsequently never gets updated, and b) we don't want to take any steps backwards in functionality.
So they can bypass ggez's drawing pipeline entirely and use their own.
Right now OpenGL is hardwired in, it would be nice to be able to support others, even if only through feature flags.
Also might be nice to offer different OpenGL versions the same way.
If we drop a frame we will attempt to play catch-up and get the simulation back to the state it should be in. This works great for occasional hiccups. But if we drop frames during the catch-up process it is possible that it will never end, and this hangs the event loop pretty hard.
Perhaps we impose a maximum number of frames to play catch-up on, and reduce it every time we hit it?
Hi, I tried to get started with ggez by putting the hello_world example into a new project, and I get this error:
$ RUST_BACKTRACE=1 cargo run
Finished dev [unoptimized + debuginfo] target(s) in 0.0 secs
Running `target/debug/ggez_test`
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: ResourceNotFound("DejaVuSerif.ttf")', /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/src/libcore/result.rs:870
stack backtrace:
1: 0x55984fe3d5cc - 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: 0x55984fe3fd3e - std::panicking::default_hook::{{closure}}::hcc803c8663cda123
at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/src/libstd/panicking.rs:351
3: 0x55984fe3f944 - std::panicking::default_hook::hd5bda4e453dfb4be
at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/src/libstd/panicking.rs:367
4: 0x55984fe4011b - std::panicking::rust_panic_with_hook::hffbc74969c7b5d87
at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/src/libstd/panicking.rs:555
5: 0x55984fe3ffb4 - std::panicking::begin_panic::hc4c5d184a1e3fb7c
at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/src/libstd/panicking.rs:517
6: 0x55984fe3fed9 - std::panicking::begin_panic_fmt::h34f5b320b0f94559
at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/src/libstd/panicking.rs:501
7: 0x55984fe3fe67 - rust_begin_unwind
at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/src/libstd/panicking.rs:477
8: 0x55984fe67a8d - core::panicking::panic_fmt::h1016b85b51d1931f
at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/src/libcore/panicking.rs:69
9: 0x55984fd2b935 - core::result::unwrap_failed::h32d58e2d95a73da2
at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/src/libcore/macros.rs:29
10: 0x55984fd26ee6 - <core::result::Result<T, E>>::unwrap::h3d9e6ceea8190f28
at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/src/libcore/result.rs:745
11: 0x55984fd36509 - <ggez_test::MainState as ggez::game::GameState>::load::h61298cceab611496
at /home/aaron/dev/rust/conway/ggez_test/src/main.rs:23
12: 0x55984fd281c8 - <ggez::game::Game<'a, S>>::new::ha71647cbf4697e3a
at /home/aaron/.cargo/registry/src/github.com-1ecc6299db9ec823/ggez-0.2.1/src/game.rs:123
13: 0x55984fd36a3d - ggez_test::main::h0bd4c5cea99ba3c8
at /home/aaron/dev/rust/conway/ggez_test/src/main.rs:53
14: 0x55984fe46faa - __rust_maybe_catch_panic
at /buildslave/rust-buildbot/slave/nightly-dist-rustc-linux/build/src/libpanic_unwind/lib.rs:98
15: 0x55984fe40886 - 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
16: 0x55984fd36d72 - main
17: 0x7f2ad825d400 - __libc_start_main
18: 0x55984fd1eb49 - _start
19: 0x0 - <unknown>
I don't understand why I am getting this error, because I have the required resource in the right location:
$ ls target/debug/resources/
DejaVuSerif.ttf
I am running the latest rust nightly, if that makes a difference:
$ rustc --version
rustc 1.16.0-nightly (ff591b6dc 2017-01-15)
Might be interesting to try to support such shenanigans. You wouldn't want to do this for a LARGE game, since all your data would probably be in memory twice (at least), but it would maybe be convenient for distributing small things.
The original setup uses a trait to defines callbacks matching Love2D's main callbacks: load, update and draw. Then you just create a new Game
object that is parametric on the type you define that trait for, which creates the object using the load callback and then runs it all. The goal was to make it match up with Love2D's model as closely as possible.
This... works, but is really quite painful to do anything fancy with. The problem is really the load callback. In Love2D everything is dynamic, so you can piece together whatever you need in that callback and it works just fine. In Rust everything is static, and so it is much harder to, say, build a scene graph or manage transitions between scenes in this. You can do it, and it works, but it needs adding a lot of machinery and management to even do something as simple as a title screen, with layers of indirection for input events and so on. Magic Happens with regards to creating the ggez Context
and bundling it together with your GameState
type, so it basically becomes impossible to disentangle any part of the initialization apart from the whole.
I experimented with splitting things apart a little, so that you just have an EventHandler
trait that handles update, draw, and event callbacks, and then separating load()
out into its own thing. It means an extra three lines of setup code when you create the game objects, but the process becomes much less twisty: you just create a Conf
, create a Context
, create whatever your EventHandler
type is with all your game data, then pass them all to a Game
to run your main loop.
Decoupling the Context
from the Game
creation also has some extra benefits, since a) you can write your own mainloop type stuff if you really want to, which appeals to some people, and b) it makes it trivial (with some minor API changes so the Game
returns the Context
when it is done) to create one Context
and thread it through several Game
objects to do simple scene transitions. Or, presumably, do the same for more sophisticated scene management.
yay? Really shouldn't make much difference, it's not like we're doing anything fancy with it.
BECAUSE, it's not multithread-able terribly well, and hides sneaky mutable state via the file handle's current read position, which makes it hard to share between multiple things. You have to open the file multiple times, at which point one might start worrying about buffering, and it's also quite inconvenient to create a new Read for each file you open in a zip, though it is possible. OR, you have to somehow share one file file handle among multiple separate readers (though an RWLock
seems the right thing here). So until I can figure out a halfway sane API for this, when we open a zip file we will just read its whole contents into memory and hang on to it there.
Looks like Travis doesn't really do this, but it'd be really nice to be able to make sure ggez at least compiles and runs minimal tests on those platforms...
Basically something that someone can just clone and get going with, which includes DLL's, a working Cargo.toml with whatever flags need to be given to the compiler, etc.
The Great Issue #29 might solve this, but also might not if there's still resource-location BS that needs doing...
Outside of tmux it works fine, running cargo run
with a project using ggez inside it and all the input goes to the terminal rather than the game.
Weird.
See the xi-unicode
crate for an implementation of this we might be able to use. Otherwise you can investigate harfbuzz or a simple hand-written thing based off glyph metrics.
Should happen eventually!
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.