Compiler Updates #

Monthly Release includes LLVM 17.0.1 support for linux and darwin.


Events #

Handmade Seattle is happening in November! Make sure to check out the event https://handmadecities.com/seattle/.


YouTube #

Rickard Andersson (gonz on Discord) continues on his odin videos

Here’s a list of what he went over this month:

Gotta catch up on these!


Games #

SabeMakesGames released his first small game done with odin! Check it out here https://sabe09.itch.io/attack-of-the-goobers

He also made a short video on it:


Editors #

obiwan87 has added support of JetBrains editors! It’s still early and doesnt support everything but its a nice start.


New / Updated Projects #

I’ll try posting the comments or descriptions the authors posted for their packages.

Journey ECS - Raigon #

Read more on: https://github.com/KDahir247/Journey_ECS

Fast Minimal Sparse set for Odin Language Which is being used in Odin-Journey.

Features:

  • Fast single component iteration & entity iteration (Dense array iteration)
  • Unlimitied amount of component can be added
  • Very minimal Only does what it needs and nothing more.
  • SOA component dense array
  • Extremely fast grouping and sub grouping query (eg. Entity with position and scale)
  • Reduced memory consumption on sparse array
  • Allow upto or more then 1 Million entity
Example of code:
package main

import ecs "foldername that has this single script"

main :: proc() {
  world := init_world()
  defer deinit_world(world)

  Position :: struct{
      val : #simd[4]f32,
  }

  Rotation :: struct{
      val : #simd[4]f32,
  }

  Scale :: struct{
      val : #simd[4]f32,
  }

  Velocity :: struct{
      val : #simd[4]f32,
  }

  register(world, Position)
  register(world, Rotation)
  register(world, Scale)
  register(world, Velocity)
  
  entity := create_entity(world)
  entity1 := create_entity(world) 
  entity2 := create_entity(world) 
  entity3 := create_entity(world) 
  entity4 := create_entity(world)

  velocityx := Velocity{
      val = {1.0, 0.0, 0.0, 0.0},
  }

  postion_x := Position{
      val = {2.0, 0.0, 0.0, 0.0},
  }

  postion_y := Position{
      val = {0.0,3.14,0.0,0.0},
  }

  position_xy := Position{
      val = {24.0,7.11,0.0,0.0},
  }
 

  Quaternion_IDENTITY := Rotation{
      val = {0.0,0.0,0.0,1.0},
  }

  add_soa_component(world, entity2, velocityx)
  add_soa_component(world, entity1, postion_x)
  add_soa_component(world, entity2, postion_y)
  add_soa_component(world, entity2, Quaternion_IDENTITY)

  add_soa_component(world, entity, position_xy)
  add_soa_component(world, entity, Quaternion_IDENTITY)

  postion_scale_query := query(world, Velocity, Scale) //register and sort using group
  position_rotation_query := query(world, Position, Rotation) //register and sort using group

  position_rotation_query1 := query(world, Position, Rotation) //doesn't register or sort using group uses the cache result
  postion_scale_query1 := query(world, Velocity, Scale) //doesn't register or sort using group uses the cache result
 
  for component_storage, index in run(&position_rotation_query){
    mut_component_storage := component_storage

    if component_storage.entities[index] == 2{
        fmt.println("Moving the player entity", component_storage.entities[index] , "Right by 100" )
        mut_component_storage.component_a[index].val += {100.0, 0.0, 0.0, 0.0}
    }

    fmt.print(component_storage.entities[index], " :\t")
    fmt.print(component_storage.component_a[index], "\t")
    fmt.print(component_storage.component_b[index])
    fmt.println()
  }
  fmt.println("\n")
}

Job Scheduler - jakubtomsu (Jacob) #

Read more on: https://github.com/jakubtomsu/jobs

I made a small job system for Odin. This is a port of my old fiber-based C++ job scheduler, but it’s much simpler and has less overhead. I also added a few examples, including boids simulation with Raylib. Features include:

  • dispatching jobs
  • waiting for jobs (while processing other queued jobs at the same time)
  • nested jobs
  • utilities for batch processing arrays/slices
  • optional immediate-mode-style thread processing loop
A simple hello world program:
main :: proc() {
    jobs.initialize()

    g: jobs.Group
    jobs.dispatch(.Medium, jobs.make_job(&g, hello_job))
    jobs.wait(&g)

    jobs.shutdown()
}

hello_job :: proc(_: rawptr) {
    fmt.println("Hello from thread", jobs.current_thread_index())
}

Cody: A simple code counter - JetDove #

Read more on: https://github.com/CoolDove/cody

...

Box2D v3 odin bindings - Cristhofer #

Read more on: https://github.com/cristhofermarques/odin-box2d/

Example:
package box2d_example

import b2 "box2d"
import "core:fmt"

main :: proc()
{
    world_def := b2.DEFAULT_WORLD_DEF
    world_def.gravity = b2.Vec2{0, -10}
    world_id := b2.create_world(&world_def)
    defer b2.destroy_world(world_id)
    
    ground_body_def := b2.DEFAULT_BODY_DEF
    ground_body_def.position = b2.Vec2{0, -10}
    ground_body_id := b2.world_create_body(world_id, &ground_body_def)

    ground_box := b2.make_box(50, 10)
    ground_shape_def := b2.DEFAULT_SHAPE_DEF
    b2.body_create_polygon(ground_body_id, &ground_shape_def, &ground_box)

    body_def := b2.DEFAULT_BODY_DEF
    body_def.type = .Dynamic
    body_def.position = b2.Vec2{0, 4}
    body_id := b2.world_create_body(world_id, &body_def)

    shape_def := b2.DEFAULT_SHAPE_DEF
    shape_def.density = 1
    shape_def.friction = 0.3

    circle: b2.Circle
    circle.radius = 1
    b2.body_create_circle(body_id, &shape_def, &circle)

    time_step: f32 = 1.0 / 60.0
    velocity_iterations: i32 = 6
    position_iterations: i32 = 2
    
    for i in 0..<60
    {
        b2.world_step(world_id, time_step, velocity_iterations, position_iterations)
        position := b2.body_get_position(body_id)
        angle := b2.body_get_angle(body_id)
        fmt.println(position, angle)
    }
}

MagicaVoxel .vox model Loader - jakubtomsu (Jacob) #

Read more on: https://github.com/jakubtomsu/odin-vox

A simple loader for .vox models from MagicaVoxel. The base format is fully implemented, but no extensions are supported yet.

Usage:
// Load and parse data from file.
// Alternatively use `vox.load_from_data`.
if data, ok := vox.load_from_file("my_model.vox", context.temp_allocator); ok {
  for model, i in data.models {
    fmt.printf("Model %i:\n", i)
    fmt.printf("\tsize: %v\n", model.size)
    fmt.printf("\tvoxels:\n")
    for voxel, j in model.voxels {
      fmt.printf("\t[%i] %v: %i\n", j, voxel.pos, voxel.color_index)
    }
  }
}

Community Showcase #

Another month has passed - this time around there was less going on but we’re nearing the end of the year.

Game Development #

We are building a 2D engine and this is our progress so far. Right now we have a custom ECS, and we have a animation system, plus we have 2D point lights implemented - ScottCastle

building a small editor for the game I'm currently toying with. Normally I just do everything in code but its nice to be able to edit colliders and such while seeing the effect. - rhoeberg

Realized my game needed branching dialogue, so I made this editor + new gameplay code for handling dialogue choices! 😺 - karl_zylinski

Trying to make my little FPS engine based on Raylib - Nefrace

Starting to put together an in-game editor, added some window management features to make it comfy. - davidcergizan

started to implement window docking because I got jealous of how slick @davidcergizans editor is looking. Still a lot of work to get it nice but I think its doable - rhoeberg

Graphics #

Got the basics working. This is a window manager for linux, written in Odin - Smilex

working on a raymarching renderer! - sandwichman

new demo! sorry for the jumpy motion, it doesn't like sharing the GPU with my recording software quite yet 😭 - sandwichman

Tools & UI #

my image splicer doing the most basic image splicing, just for the end of the jam - Stvff

...

After so many hours of headbanging against manpages and 3 odin internal compiler errors found, I've managed to start writing a debugger... - flysand

...

got custom win32 window borders working for my platform layer 🎉 - Skytrias

Miscellaneous #

...

Working on a MIPS assembler for a personal project. I'm really bad at parsing but here is my first progress update in which I am successfully validating token sequences that correspond to the instructions. - Heinrich

Made my go-to thing to make in a new language - a Brainfuck compiler - Only generates naïve code for linux-x64 but I might add more backends and some optimizations - Danie

...

My first test run of my MIPS assembler producing a binary usable by my emulator. - Heinrich

...

The true purpose of the emulator. I am associating part of the memory with a text display beginning at 0x400. - Heinrich