Giter Club home page Giter Club logo

yeti's People

Contributors

mtwilliams avatar noct 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

Watchers

 avatar  avatar  avatar

yeti's Issues

Properly track resource compilation.

We need to tracking the result of each individual compilation, including logs. We could store a log of this into a SQLite3 database (data/compiler.db).

Sophisticated crash handling.

We should handle crashes very gracefully, doing everything we can to make debugging the issue easier. This culminates into:

  • Dumping registers
  • Dumping callstack, including Lua
  • Dumping global state, specifically how memory is allocated
  • Producing a crash dump, allowing postmortem debugging

Allow multiple source data trees.

For example, source data could be broken down into:

  • core
  • sample/01-hello-world
  • sample/02-cube
  • ...

And layered per-project to allow common code and data to be shared.

Improve default assertion handler.

We should provide:

  • Regsiters
  • Callstack
  • Crash dump, for postmortem debugging

This is suspiciously what a crash handler should provide, so we should probably just fall through to a crash.

Move to Ryb.

This, obviously, requires me to get Ryb to a mature enough state.

Reduce boilerplate required to load resources.

Currently to load vanguard/boot.lua we have to perform this song and dance:

const Resource::Type *script_resource_type = resource_manager::type_from_name("script");
const Resource::Type::Id script_resource_type_id = resource_manager::id_from_type(script_resource_type);
const Resource::Id script_resource_id = Resource::id_from_type_and_name(script_resource_type_id, "vanguard/boot");
ScriptResource *script_resource = (ScriptResource *)resource_manager::load(script_resource_id);
while (script_resource->state() != Resource::LOADED);

We should simplify it to something like:

ScriptResource *script_resource = resource_manager::load<ScriptResource *>("vanguard/boot");
while (script_resource->state() != Resource::LOADED);

Resource packages.

Basically just a resource with a shit tonne of dependencies.

A package would look something like this:

// We load our menu and gameplay code asynchronously.
//  See `vanguard/menus.package`
//  See `vanguard/gameplay.package`
scripts = [
  "vanguard/boot",
  "vanguard/splash"
]

textures = [
  "vanguard/textures/splash/legal",
  "vanguard/textures/splash/engine",
  "vanguard/textures/splash/spinner",
  "vanguard/textures/splash/background"
]

vanguard/boot.package

Build a brand.

I had a logo (and color scheme) made by Donatas Surgailis a little while back. It's beyond lovely. This should be leveraged into a web presence, as well as assets for splash screens and the like.

Logo Spec

Freezes window manager?

The following boot script causes Windows' window manager to completely freeze. Killing the runtime by pressing the power button immediately unfreezes it. This may be the culmination of an uncapped update rate (i.e. 1000s of times a second) and setting the window title -- literally causing a denial of service attack.

-- === vanguard/boot.lua --------------------------------*- mode: Lua -*--=== --
--                                                                            --
--                     _____                           _                      --
--                    |  |  |___ ___ ___ _ _ ___ ___ _| |                     --
--                    |  |  | .'|   | . | | | .'|  _| . |                     --
--                     \___/|__,|_|_|_  |___|__,|_| |___|                     --
--                                  |___|                                     --
--                                                                            --
--       This file is distributed under the terms described in LICENSE.       --
--                                                                            --
-- -------------------------------------------------------------------------- --

local window = window or nil

function startup()
  window = Window.open({title="Vanguard™", width=1280, height=720})
  Window.show(window)
end

function shutdown()
  Window.close(window)
end

function update(delta_time)
  if Keyboard.pressed('escape') then
    Application.quit()
  end

  if Mouse.held('left') then
    local relative = Mouse.axis('relative')
    local title = string.format("Vanguard™ (x=%d, y=%d)", Vec3.x(relative), Vec3.y(relative))
    Window.set_title(window, title)
  end

  if Mouse.pressed('left') then
    Window.clip(window)
  elseif Mouse.released('left') then
    Window.unclip(window)
  end
end

function render()
end

Add smoothed time-step policy.

A smoothed time-step policy should be added. Using historical frame times, it should smooth out any spikes. Additionally, a "payback" version should added, to prevent desynchronization issues in multiplayer.

Reimplement task system with the least overhead possible and with the ability to perform on-the-fly changes to the task graph.

A recent commit, 4a0423c, added a preliminary and tentative version of bt_task_t and butane::Task in include/butane/task.h. It's based on Niklas Frykholm's blog post "Task Management -- A Practical Example" which describes task management in the Bitsquid engine. Similar task management was implemented prior to this refactor, and like Bitsquid's implementation used a critical section to access a global queue. There were no performance concerns, until profiling revealed high lock contention when approximately twenty or more tasks were enqueued. This was the result of worker threads working through quite a few non-consumable tasks prior to finding work, as a consequence of how a consumable task was identified.

The following is a pseduo-code representation of the current worker thread's loop:

while true:
  task = tasks.dequeue()
  if not task.consumable?:
    tasks.enqueue(task)
    continue
  task.consume()

Upon closer inspection you will notice few things:

  1. Locking is opaquely handled in tasks.enqueue() and tasks.dequeue() meaning two blocking locks for each non-consumable task. Ouch.
  2. Queue smashing consequently leading to increased search times for worker threads that only find task.consumable? for the the requeued task.
  3. Memory is being touched randomly.
  4. Priority would be inefficiently and non-simplistically handled.

So, instead a worker thread's loop should look something like this:

while true:
  if tasks.empty?
    continue
  tasks.lock()
  consumable = nil
  for each task in tasks:
    if task.consumable?:
      if consumable and consumable.priority < task.priority:
        consumable = task
  if consumable:
    tasks.remove(consumable)
  tasks.unlock()
  if consumable:
    consumable.consume()

This solves the noted issues:

  1. Locking is now explicitly handled by tasks.lock() and tasks.unlock() meaning only one lock for the entire search.
  2. Search times are now 'constant' and no queue smashing occurs.
  3. Memory is being touched linearly.
  4. Priority is handled efficiently and simplistically.

A further but minor concern is context switches, as pointed out by Niklas. The effects are visible below, in a commented screenshot of Bitsquid's task profiling tool:

A commented screenshot of Bitsquid's task profiling tool

These might be mitigated by using the Thread Pool API on Windows and Grand Central Dispatch on Mac OSX and iOS. Linux, BSD, and Android might have something similar.


Previous title, "Rewrite worker threads to reduce lock contention and improve performance."

Expose SetCursor and ClipCursor.

That way, games can disable the cursor and prevent it from running off-screen in multi-monitor setups, and tools can provide contextual hints via the mouse cursor (e.g. a grabbing cursor when moving an object).

Custom logging.

We need proper logging infrastructure.

We should start with unstructured (plaintext) thread-safe logging with logging levels. Later, we should extend to structured logging, which allows us to serialize plain ol' data.

Provide an appropriate license.

Basically,

You're free to do what you want but we're not responsible.

We ask that you (1) display a provided splash screen and (2) don't misattribute where the code and functionality came from.

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.