<?xml version='1.0' encoding='utf-8'?>
<?xml-stylesheet type="text/xsl" href="/sheet.xsl"?><rss version="2.0"><channel><title>Hacker News</title><link>https://news.ycombinator.com/</link><description>Links for the intellectually curious, ranked by readers.</description><item><title>OpenRouter raises $113M Series B</title><link>https://openrouter.ai/announcements/series-b</link><pubDate>Sat, 30 May 2026 17:27:28 +0000</pubDate><comments>https://news.ycombinator.com/item?id=48338660</comments><description>&lt;a href="https://news.ycombinator.com/item?id=48338660"&gt;Comments&lt;/a&gt;</description><ns0:encoded xmlns:ns0="http://purl.org/rss/1.0/modules/content/">&lt;article class="flex flex-col gap-6 px-8" morss_own_score="4.423312883435583" morss_score="12.985812883435582"&gt;&lt;h1&gt;OpenRouter Raises $113M Series B&lt;/h1&gt;&lt;p&gt;OpenRouter · &lt;time&gt;5/28/2026&lt;/time&gt;&lt;/p&gt;&lt;img src="https://openrouter.ai/_next/image?url=%2Fimages%2Fblog%2Fseries-b.png&amp;amp;w=3840&amp;amp;q=75&amp;amp;dpl=dpl_759dHfa9M2hqRqohcC736WRwsxLz"&gt;&lt;div class="prose-slate prose-hr:border-current prose-table:min-w-full prose-table:overflow-hidden prose-table:rounded-lg prose-table:border prose-table:border-current prose-ol:list-decimal prose-ol:pl-8 prose-ul:list-disc prose-ul:pl-8 prose-ol:pb-4 prose-ul:pb-4 prose-li:whitespace-normal prose-th:border prose-th:border-current prose-th:px-4 prose-th:py-2 prose-td:border prose-td:border-current prose-td:px-4 prose-td:py-2 prose-h3:font-medium prose-h3:text-current prose-p:break-words prose-p:leading-6 prose-p:whitespace-pre-wrap prose-blockquote:border-l-2 prose-blockquote:pl-4 prose-blockquote:italic prose-blockquote:border-slate-10 prose-blockquote:text-slate-11 prose-img:max-w-full prose-img:h-auto prose-img:rounded-lg prose-img:shadow-sm prose-img:my-4 prose-img:mx-auto prose-img:block tracking-tight flex flex-col gap-6" morss_own_score="3.125" morss_score="27.625"&gt;&lt;p&gt;Today we're announcing our $113M Series B, led by &lt;a href="https://capitalg.com/"&gt;CapitalG&lt;span&gt;(opens in new tab)&lt;/span&gt;&lt;/a&gt; (Alphabet's independent growth fund), with participation from &lt;a href="https://www.nvidia.com/en-us/about-nvidia/nventures/"&gt;NVentures&lt;span&gt;(opens in new tab)&lt;/span&gt;&lt;/a&gt; (NVIDIA's venture capital arm), &lt;a href="https://www.servicenow.com/"&gt;ServiceNow&lt;span&gt;(opens in new tab)&lt;/span&gt;&lt;/a&gt; Ventures, &lt;a href="https://www.mongodb.com/"&gt;MongoDB&lt;span&gt;(opens in new tab)&lt;/span&gt;&lt;/a&gt; Ventures, &lt;a href="https://www.snowflake.com/"&gt;Snowflake&lt;span&gt;(opens in new tab)&lt;/span&gt;&lt;/a&gt; Ventures, &lt;a href="https://www.databricks.com/"&gt;Databricks&lt;span&gt;(opens in new tab)&lt;/span&gt;&lt;/a&gt; Ventures, &lt;a href="https://amppublic.com/"&gt;AMP PBC&lt;span&gt;(opens in new tab)&lt;/span&gt;&lt;/a&gt;, and &lt;a href="https://pacecapital.com/"&gt;Pace Capital&lt;span&gt;(opens in new tab)&lt;/span&gt;&lt;/a&gt;, alongside our existing investors &lt;a href="https://a16z.com/"&gt;Andreessen Horowitz&lt;span&gt;(opens in new tab)&lt;/span&gt;&lt;/a&gt; and &lt;a href="https://menlovc.com/"&gt;Menlo Ventures&lt;span&gt;(opens in new tab)&lt;/span&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Where we are&lt;/h2&gt;
&lt;p&gt;Over the last six months, weekly volume on OpenRouter has grown from 5 trillion to 25 trillion tokens. We are on pace to process over a quadrillion tokens this year and serve 8M+ developers building across 400+ models. AI is rapidly shifting from experimentation into critical production apps and agents, and that transition requires infrastructure that works reliably at scale, across providers, across modalities, and across use cases. This growth reflects the simple fact that developers love building on OpenRouter.&lt;/p&gt;
&lt;h2&gt;Why this round matters&lt;/h2&gt;
&lt;p&gt;The composition of this investor group is deliberate. CapitalG, NVentures, ServiceNow Ventures, MongoDB Ventures, Snowflake Ventures, and Databricks Ventures are more than financial backers; they are the infrastructure and platform companies that enterprises already depend on. Their participation reflects a shared view: as organizations move from single-model pilots to multi-model production systems, they need a routing and gateway layer purpose-built for that complexity.&lt;/p&gt;
&lt;p&gt;OpenRouter is that layer. We sit between agents and model providers, handling the routing, reliability, cost optimization, and compliance that production AI demands. The breadth of strategic investors in this round signals that the market has converged on this as a critical piece of the stack.&lt;/p&gt;
&lt;h2&gt;What we've been building&lt;/h2&gt;
&lt;p&gt;The past year has been focused on expanding what OpenRouter can do for production workloads:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Multimodal inference&lt;/strong&gt;: Beyond text, OpenRouter now supports &lt;a href="https://openrouter.ai/models?output_modalities=image"&gt;image&lt;span&gt;(opens in new tab)&lt;/span&gt;&lt;/a&gt;, &lt;a href="https://openrouter.ai/models?output_modalities=audio"&gt;audio&lt;span&gt;(opens in new tab)&lt;/span&gt;&lt;/a&gt;, &lt;a href="https://openrouter.ai/models?output_modalities=speech"&gt;speech&lt;span&gt;(opens in new tab)&lt;/span&gt;&lt;/a&gt;, &lt;a href="https://openrouter.ai/models?output_modalities=transcription"&gt;transcription&lt;span&gt;(opens in new tab)&lt;/span&gt;&lt;/a&gt;, &lt;a href="https://openrouter.ai/models?output_modalities=embedding"&gt;embedding&lt;span&gt;(opens in new tab)&lt;/span&gt;&lt;/a&gt;, and &lt;a href="https://openrouter.ai/models?output_modalities=video"&gt;video&lt;span&gt;(opens in new tab)&lt;/span&gt;&lt;/a&gt; models.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Enterprise controls&lt;/strong&gt;: &lt;a href="https://openrouter.ai/docs/guides/features/workspaces"&gt;Workspaces&lt;span&gt;(opens in new tab)&lt;/span&gt;&lt;/a&gt;, spend management, &lt;a href="https://openrouter.ai/docs/guides/features/guardrails"&gt;guardrails&lt;span&gt;(opens in new tab)&lt;/span&gt;&lt;/a&gt;, and &lt;a href="https://openrouter.ai/docs/guides/privacy/zero-data-retention"&gt;zero-data-retention&lt;span&gt;(opens in new tab)&lt;/span&gt;&lt;/a&gt; policies for organizations deploying AI at scale.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Intelligent routing&lt;/strong&gt;: Provider-level failover, cost and latency optimization, and quality-aware routing that goes beyond simple load balancing.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;What's next&lt;/h2&gt;
&lt;p&gt;We'll use this funding to continue scaling our infrastructure, deepen enterprise capabilities, and continue to invest in intelligent routing; teams need help finding the right model and provider for every request. We're grateful to our customers, partners, investors, and the developer community building with us as we continue scaling the infrastructure layer for the multi-model AI era.&lt;/p&gt;&lt;/div&gt;&lt;/article&gt;</ns0:encoded></item><item><title>Zig ELF Linker Improvements Devlog</title><link>https://ziglang.org/devlog/2026/#2026-05-30</link><pubDate>Sat, 30 May 2026 17:29:22 +0000</pubDate><comments>https://news.ycombinator.com/item?id=48338673</comments><description>&lt;a href="https://news.ycombinator.com/item?id=48338673"&gt;Comments&lt;/a&gt;</description><ns0:encoded xmlns:ns0="http://purl.org/rss/1.0/modules/content/">&lt;div class="changelist" morss_own_score="2.7610037841067516" morss_score="13.777189001744025"&gt;
&lt;div id="2026-05-30" morss_own_score="2.8641509433962264" morss_score="36.713757745248806"&gt;
&lt;span&gt;May 30, 2026&lt;/span&gt;
&lt;h1&gt;&lt;a href="https://ziglang.org/devlog/2026/#2026-05-30"&gt;ELF Linker Improvements
&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Author: Matthew Lugg&lt;/p&gt;&lt;p&gt;I’ve spent the past few weeks working on our new ELF linker which debuted in Zig 0.16.0. At the time of the 0.16.0 release, this linker implementation was in its fairly early stages, and only really supported linking Zig-only code without any external libraries (even libc)—hence why it was (and still is) disabled by default (it can be enabled with &lt;code&gt;-fnew-linker&lt;/code&gt;). However, quite a lot of progress has been made since that initial release!&lt;/p&gt;&lt;p&gt;Here’s a nice milestone—as of &lt;a href="https://codeberg.org/ziglang/zig/pulls/35533"&gt;my latest PR&lt;/a&gt;, the new ELF linker is capable of building the self-hosted Zig compiler with LLVM and LLD libraries enabled, a task which requires quite a few features under the hood.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;[&lt;span&gt;mlugg&lt;/span&gt;&lt;span&gt;@nebula&lt;/span&gt; &lt;span&gt;master]&lt;/span&gt;&lt;span&gt;$&lt;/span&gt; &lt;span&gt;# Build the Zig compiler using the new linker:&lt;/span&gt;
&lt;span&gt;[mlugg@nebula&lt;/span&gt; &lt;span&gt;master]&lt;/span&gt;&lt;span&gt;$&lt;/span&gt; &lt;span&gt;zig&lt;/span&gt; &lt;span&gt;build&lt;/span&gt; &lt;span&gt;-Dno-lib&lt;/span&gt; &lt;span&gt;-Dnew-linker&lt;/span&gt; &lt;span&gt;-Denable-llvm&lt;/span&gt;
&lt;span&gt;[mlugg@nebula&lt;/span&gt; &lt;span&gt;master]&lt;/span&gt;&lt;span&gt;$&lt;/span&gt; &lt;span&gt;# Use that compiler to build something with LLVM and LLD:&lt;/span&gt;
&lt;span&gt;[mlugg@nebula&lt;/span&gt; &lt;span&gt;master]&lt;/span&gt;&lt;span&gt;$&lt;/span&gt; &lt;span&gt;./zig-out/bin/zig&lt;/span&gt; &lt;span&gt;build-exe&lt;/span&gt; &lt;span&gt;~/hello.zig&lt;/span&gt; &lt;span&gt;-fllvm&lt;/span&gt; &lt;span&gt;-flld&lt;/span&gt;
&lt;span&gt;[mlugg@nebula&lt;/span&gt; &lt;span&gt;master]&lt;/span&gt;&lt;span&gt;$&lt;/span&gt; &lt;span&gt;./hello&lt;/span&gt;
&lt;span&gt;Hello,&lt;/span&gt; &lt;span&gt;World!&lt;/span&gt;
&lt;span&gt;[mlugg@nebula&lt;/span&gt; &lt;span&gt;master]&lt;/span&gt;&lt;span&gt;$&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Of course, an ELF linker isn’t necessarily the most exciting thing in the world, which is why the headline feature of this new linker is its support for fast incremental compilation. After the recent enhancements, it is now possible (on x86_64 Linux) to perform incremental rebuilds while linking external libraries, C sources, etc—without any additional performance overhead! Here’s a clip of me trying it out on &lt;a href="https://github.com/andrewrk/tetris"&gt;Andrew’s Tetris clone&lt;/a&gt;:&lt;/p&gt;&lt;p&gt;&lt;figure&gt;&lt;figcaption&gt;A few silly changes to Andrew’s Tetris clone being built in around 30ms each.&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;&lt;p&gt;Oh, and fast incremental rebuilds also work nicely on the Zig compiler itself:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;[mlugg@nebula master]$ zig build -Dno-lib -Denable-llvm -fincremental --watch
Build Summary: 4/4 steps succeeded
install success
└─ install zig success
   └─ compile exe zig Debug native success 36s

Build Summary: 4/4 steps succeeded
install success
└─ install zig success
   └─ compile exe zig Debug native success 244ms

Build Summary: 4/4 steps succeeded
install success
└─ install zig success
   └─ compile exe zig Debug native success 228ms

Build Summary: 4/4 steps succeeded
install success
└─ install zig success
   └─ compile exe zig Debug native success 288ms

Build Summary: 4/4 steps succeeded
install success
└─ install zig success
   └─ compile exe zig Debug native success 283ms
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The biggest missing feature of this linker implementation right now is that it still does not yet support generating DWARF debug information for Zig code—that’s definitely my next priority. But even without that support, it’s amazing just how useful instant rebuilds can be, for example in any situation where you’re doing a lot of print debugging.&lt;/p&gt;&lt;p&gt;If you’re using the master branch of Zig and you’re on x86_64 Linux, consider trying out incremental compilation with the new ELF linker if it previously wasn’t working with your project! I expect many codebases to already work great with it, unlocking the ability to rebuild your project in milliseconds. Of course, if you come across any bugs, please do &lt;a href="https://codeberg.org/ziglang/zig/issues"&gt;open an issue&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;And if you’re currently sticking to tagged releases of Zig, don’t worry—as Andrew mentioned in his last devlog, Zig 0.17.0 is just around the corner, so it won’t be long before you can try this too!&lt;/p&gt;
&lt;/div&gt;
&lt;div id="2026-05-26" morss_own_score="2.8980392156862744" morss_score="50.398039215686275"&gt;
&lt;span&gt;May 26, 2026&lt;/span&gt;
&lt;h1&gt;&lt;a href="https://ziglang.org/devlog/2026/#2026-05-26"&gt;Build System Reworked
&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Author: Andrew Kelley&lt;/p&gt;&lt;p&gt;Big branch just landed: &lt;a href="https://codeberg.org/ziglang/zig/pulls/35428"&gt;separate the maker process from the configurer process&lt;/a&gt;&lt;/p&gt;&lt;p&gt;This devlog entry is essentially a preview of the upcoming release notes, but serves as an advanced notice to those who want to help test out the new features and provide feedback that will guide the Zig project moving forward.&lt;/p&gt;&lt;p&gt;Before, &lt;code&gt;build.zig&lt;/code&gt; files plus the build system implementation were all compiled into one bloated process, in Debug mode. After &lt;code&gt;build.zig&lt;/code&gt; logic finished constructing a build graph in memory, the “build runner” code executed it.&lt;/p&gt;&lt;p&gt;Now, &lt;code&gt;build.zig&lt;/code&gt; files are compiled into a small process (the “configurer”) in debug mode. After this logic finishes constructing a build graph in memory, it is serialized to a binary configuration file. The parent &lt;code&gt;zig build&lt;/code&gt; process is aware of this file and caches it for next time. While waiting for all that, it asynchronously compiles the build graph execution process (the “maker”) in release mode. Once the configuration file is available and the maker process is finished compiling, the maker process is executed, passing it the configuration file. The maker process only needs to be compiled once per &lt;code&gt;zig version&lt;/code&gt; thanks to the global cache. The maker process then executes the build graph, which is contained within the serialized configuration file.&lt;/p&gt;&lt;p&gt;The primary motivation of this change was to make &lt;code&gt;zig build&lt;/code&gt; faster, in three ways:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;Only the user’s &lt;code&gt;build.zig&lt;/code&gt; logic will be compiled with each change, rather than the entire build system along with it. This is starting to become more valuable now that we have introduced &lt;code&gt;--watch&lt;/code&gt;, &lt;code&gt;--fuzz&lt;/code&gt; and &lt;code&gt;--webui&lt;/code&gt;. The build system can grow more features without making &lt;code&gt;zig build&lt;/code&gt; take longer.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Now the build system can skip rerunning the &lt;code&gt;build.zig&lt;/code&gt; logic entirely when it knows nothing will change, for example if you add &lt;code&gt;-freference-trace&lt;/code&gt; to your &lt;code&gt;zig build&lt;/code&gt; command line, it now avoids re-running your &lt;code&gt;build.zig&lt;/code&gt; logic redundantly, using the same configuration as last time.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Now the process that actually executes the build graph is compiled with optimizations enabled.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;To demonstrate points 2 and 3, here is the difference between running &lt;code&gt;zig build --help&lt;/code&gt; before and after:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;Benchmark 1 (34 runs): master/zig build -h
  measurement          mean ± σ            min … max           outliers         delta
  wall_time           150ms ± 5.52ms     145ms …  165ms          4 (12%)        0%
  peak_rss           84.8MB ±  275KB    84.2MB … 85.1MB          0 ( 0%)        0%
  cpu_cycles          593M  ± 4.01M      588M  …  608M           2 ( 6%)        0%
  instructions        995M  ± 52.5K      995M  …  995M           0 ( 0%)        0%
  cache_references   25.8M  ±  165K     25.4M  … 26.1M           0 ( 0%)        0%
  cache_misses        651K  ± 20.1K      619K  …  697K           0 ( 0%)        0%
  branch_misses       918K  ± 7.44K      906K  …  935K           0 ( 0%)        0%
Benchmark 2 (348 runs): branch/zig build -h
  measurement          mean ± σ            min … max           outliers         delta
  wall_time          14.3ms ±  744us    13.2ms … 23.3ms          8 ( 2%)        ⚡- 90.4% ±  0.4%
  peak_rss           78.5MB ±  562KB    77.1MB … 81.4MB          7 ( 2%)        ⚡-  7.4% ±  0.2%
  cpu_cycles         24.1M  ±  821K     22.8M  … 27.1M           3 ( 1%)        ⚡- 95.9% ±  0.1%
  instructions       43.7M  ± 23.8K     43.7M  … 43.8M          56 (16%)        ⚡- 95.6% ±  0.0%
  cache_references   1.46M  ± 14.6K     1.40M  … 1.50M          19 ( 5%)        ⚡- 94.3% ±  0.1%
  cache_misses        142K  ± 4.87K      127K  …  157K           2 ( 1%)        ⚡- 78.1% ±  0.4%
  branch_misses       126K  ± 1.37K      120K  …  129K          12 ( 3%)        ⚡- 86.3% ±  0.1%
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;It’s dramatic because before, &lt;code&gt;build.zig&lt;/code&gt; logic was being executed with each &lt;code&gt;zig build&lt;/code&gt; command, but now, the build system uses the cached, serialized configuration instead.&lt;/p&gt;&lt;p&gt;Aside from performance, I expect third-party tooling such as ZLS to benefit from consuming the serialized configuration file rather than maintaining a fork of the build runner.&lt;/p&gt;&lt;p&gt;This changeset heavily reworks the internal mechanism of the zig build system, however, it is mostly non-breaking from an API perspective, with the exceptions noted in the PR linked above.&lt;/p&gt;&lt;p&gt;For most people I’m guessing this is the main breaking change they’ll hit:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;if&lt;/span&gt; &lt;span&gt;(&lt;/span&gt;&lt;span&gt;b&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;args&lt;/span&gt;&lt;span&gt;)&lt;/span&gt; &lt;span&gt;|&lt;/span&gt;&lt;span&gt;args&lt;/span&gt;&lt;span&gt;|&lt;/span&gt; &lt;span&gt;{&lt;/span&gt;
    &lt;span&gt;run_cmd&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;addArgs&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;args&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;
&lt;span&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;⬇️&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;run_cmd&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;addPassthruArgs&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This removes a capability from build scripts since they can no longer observe those arguments. In exchange, it means that when changing those arguments, build scripts no longer must be rebuilt from source.&lt;/p&gt;&lt;p&gt;If you’re someone who wants to influence the direction of Zig, this is a good time to upgrade your projects to the development version and try out these changes. We’ll be releasing 0.17.0 within a couple weeks from now. However, if you don’t have time, and you find out that 0.17.0 broke your build, don’t worry, there will be plenty of opportunity to get fixes in for the 0.17.1 tag as well.&lt;/p&gt;
&lt;/div&gt;
&lt;div id="2026-04-08" morss_own_score="2.804560260586319" morss_score="23.345543867143697"&gt;
&lt;span&gt;April 08, 2026&lt;/span&gt;
&lt;h1&gt;&lt;a href="https://ziglang.org/devlog/2026/#2026-04-08"&gt;Incremental compilation with LLVM
&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Author: Matthew Lugg&lt;/p&gt;&lt;p&gt;I’ve been spending a bit of time working on personal projects after merging my &lt;a href="https://ziglang.org/devlog/2026/#2026-03-10"&gt;type resolution changes&lt;/a&gt; last month, but I did find the time recently to make some improvements to the LLVM codegen backend. This involved a few different enhancements with various goals, but one nice user-facing change was that I managed to get incremental compilation working with the LLVM backend.&lt;/p&gt;&lt;p morss_own_score="7.0" morss_score="11.0"&gt;Sadly this can’t do anything to speed up the dreaded LLVM Emit Object: that time is entirely down to LLVM. However, what incremental compilation &lt;em&gt;does&lt;/em&gt; help with is minimizing the time spent in the actual Zig compiler code, which means that if your code has compile errors (so “LLVM Emit Object” will be skipped), you’ll usually get those errors very quickly. (Of course, it does still give you a &lt;em&gt;slight&lt;/em&gt; speed-up in successful builds too.)&lt;/p&gt;&lt;p&gt;This support is available in master branch builds right now, and will be in the 0.16.0 release (which we’ll be tagging very soon).&lt;/p&gt;&lt;p&gt;For anyone who still hasn’t tried it, especially if you’re using Zig’s master branch, please do try out incremental compilation by passing &lt;code&gt;-fincremental --watch&lt;/code&gt; to &lt;code&gt;zig build&lt;/code&gt;! The Zig core team have benefited from incremental compilation in our workflows for a good year now, and we’re also hearing good things from users. The feature is relatively stable at this point, and people are often surprised how much time they can save just by getting up-to-date compile errors in milliseconds rather than seconds.&lt;/p&gt;&lt;p&gt;I haven’t really personally used incremental compilation with the LLVM backend, but all of the incremental test coverage in CI is now enabled for the LLVM backend, and I’ve had positive feedback from users, so it’s definitely worth giving a shot. As always, if you encounter bugs in incremental compilation, please report them if you can!&lt;/p&gt;&lt;p&gt;Thank you, and I hope you find this useful :)&lt;/p&gt;
&lt;/div&gt;
&lt;div id="2026-03-10" morss_own_score="2.7709090909090905" morss_score="36.71578088578089"&gt;
&lt;span&gt;March 10, 2026&lt;/span&gt;
&lt;h1&gt;&lt;a href="https://ziglang.org/devlog/2026/#2026-03-10"&gt;Type resolution redesign, with language changes to taste
&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Author: Matthew Lugg&lt;/p&gt;&lt;p&gt;Today, &lt;a href="https://codeberg.org/ziglang/zig/pulls/31403"&gt;I merged a 30,000 line PR&lt;/a&gt; after two (arguably three) months of work. The goal of this branch was to rework the Zig compiler’s internal type resolution logic to a more logical and straightforward design. It’s a quite exciting change for me personally, because it allowed me to clean up a bunch of the compiler guts, but it also has some nice user-facing changes which you might be interested in!&lt;/p&gt;&lt;p&gt;For one thing, the Zig compiler is now lazier about analyzing the fields of types: if the type is never initialized, then there’s no need for Zig to care what that type “looks like”. This is important when you have a type which doubles as a namespace, a common pattern in modern Zig. For instance, when using &lt;code&gt;std.Io.Writer&lt;/code&gt;, you don’t want the compiler to also pull in a bunch of code in &lt;code&gt;std.Io&lt;/code&gt;! Here’s a straightforward example:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;const&lt;/span&gt; &lt;span&gt;Foo&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; &lt;span&gt;struct&lt;/span&gt; &lt;span&gt;{&lt;/span&gt;
    &lt;span&gt;bad_field&lt;/span&gt;&lt;span&gt;:&lt;/span&gt; &lt;span&gt;@compileError&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;"i am an evil field, muahaha"&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;
    &lt;span&gt;const&lt;/span&gt; &lt;span&gt;something&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; &lt;span&gt;123&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;
&lt;span&gt;}&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;
&lt;span&gt;comptime&lt;/span&gt; &lt;span&gt;{&lt;/span&gt;
    &lt;span&gt;_&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; &lt;span&gt;Foo&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;something&lt;/span&gt;&lt;span&gt;;&lt;/span&gt; &lt;span&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Previously, this code emitted a compile error. Now, it compiles just fine, because Zig never actually looks at the &lt;code&gt;@compileError&lt;/code&gt; call.&lt;/p&gt;&lt;p&gt;Another improvement we’ve made is in the “dependency loop” experience. Anyone who has encountered a dependency loop compile error in Zig before knows that the error messages for them are entirely unhelpful—but that’s now changed! If you encounter one (which is also a bit less likely now than it used to be), you’ll get a detailed error message telling you exactly where the dependency loop comes from. Check it out:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;const&lt;/span&gt; &lt;span&gt;Foo&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; &lt;span&gt;struct&lt;/span&gt; &lt;span&gt;{&lt;/span&gt; &lt;span&gt;inner&lt;/span&gt;&lt;span&gt;:&lt;/span&gt; &lt;span&gt;Bar&lt;/span&gt; &lt;span&gt;}&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;
&lt;span&gt;const&lt;/span&gt; &lt;span&gt;Bar&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; &lt;span&gt;struct&lt;/span&gt; &lt;span&gt;{&lt;/span&gt; &lt;span&gt;x&lt;/span&gt;&lt;span&gt;:&lt;/span&gt; &lt;span&gt;u32&lt;/span&gt; &lt;span&gt;align&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;@alignOf&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;Foo&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;)&lt;/span&gt; &lt;span&gt;}&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;
&lt;span&gt;comptime&lt;/span&gt; &lt;span&gt;{&lt;/span&gt;
    &lt;span&gt;_&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; &lt;span&gt;@as&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;Foo&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;undefined&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;
&lt;span&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$ zig build-obj repro.zig
error: dependency loop with length 2
    repro.zig:1:29: note: type 'repro.Foo' depends on type 'repro.Bar' for field declared here
    const Foo = struct { inner: Bar };
                                ^~~
    repro.zig:2:44: note: type 'repro.Bar' depends on type 'repro.Foo' for alignment query here
    const Bar = struct { x: u32 align(@alignOf(Foo)) };
                                               ^~~
    note: eliminate any one of these dependencies to break the loop
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Of course, dependency loops can get much more complicated than this, but in every case I’ve tested, the error message has had enough information to easily see what’s going on.&lt;/p&gt;&lt;p&gt;Additionally, this PR made big improvements to the Zig compiler’s “incremental compilation” feature. The short version is that it fixed a huge amount of known bugs, but in particular, “over-analysis” problems (where an incremental update did more work than should be necessary, sometimes by a big margin) should finally be all but eliminated—making incremental compilation significantly faster in many cases! If you’ve not already, consider &lt;a href="https://ziglang.org/download/0.15.1/release-notes.html#Incremental-Compilation"&gt;trying out incremental compilation&lt;/a&gt;: it really is a lovely development experience. This is for sure the improvement which excites me the most, and a large part of what motivated this change to begin with.&lt;/p&gt;&lt;p&gt;There are a bunch more changes that come with this PR—dozens of bugfixes, some small language changes (mostly fairly niche), and compiler performance improvements. It’s far too much to list here, but if you’re interested in reading more about it, you can take a look at &lt;a href="https://codeberg.org/ziglang/zig/pulls/31403"&gt;the PR&lt;/a&gt; on Codeberg—and of course, if you encounter any bugs, please do open an issue. Happy hacking!&lt;/p&gt;
&lt;/div&gt;
&lt;div id="2026-02-13" morss_own_score="2.730125523012552" morss_score="43.23012552301255"&gt;
&lt;span&gt;February 13, 2026&lt;/span&gt;
&lt;h1&gt;&lt;a href="https://ziglang.org/devlog/2026/#2026-02-13"&gt;io_uring and Grand Central Dispatch std.Io implementations landed
&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Author: Andrew Kelley&lt;/p&gt;&lt;p&gt;As we approach the end of the 0.16.0 release cycle, Jacob has been hard at work, bringing &lt;code&gt;std.Io.Evented&lt;/code&gt; up to speed with all the latest API changes:&lt;/p&gt;&lt;p&gt;Both of these are based on userspace stack switching, sometimes called “fibers”, “stackful coroutines”, or “green threads”.&lt;/p&gt;&lt;p morss_own_score="7.0" morss_score="11.0"&gt;They are now &lt;strong&gt;available to tinker with&lt;/strong&gt;, by constructing one’s application using &lt;code&gt;std.Io.Evented&lt;/code&gt;. They should be considered &lt;strong&gt;experimental&lt;/strong&gt; because there is important followup work to be done before they can be used reliably and robustly:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="https://codeberg.org/ziglang/zig/issues/31199"&gt;better error handling&lt;/a&gt;&lt;/li&gt;&lt;li&gt;remove the logging&lt;/li&gt;&lt;li&gt;diagnose the unexpected performance degradation when using &lt;code&gt;IoMode.evented&lt;/code&gt; for the compiler&lt;/li&gt;&lt;li&gt;&lt;a href="https://codeberg.org/ziglang/zig/issues/31200"&gt;a couple functions still unimplemented&lt;/a&gt;&lt;/li&gt;&lt;li&gt;more test coverage is needed&lt;/li&gt;&lt;li&gt;&lt;a href="https://github.com/ziglang/zig/issues/157"&gt;builtin function to tell you the maximum stack size of a given function&lt;/a&gt; to make these implementations practical to use when overcommit is off.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;With those caveats in mind, it seems we are indeed reaching the Promised Land, where Zig code can have Io implementations effortlessly swapped out:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;const&lt;/span&gt; &lt;span&gt;std&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; &lt;span&gt;@import&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;"std"&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;

&lt;span&gt;pub&lt;/span&gt; &lt;span&gt;fn&lt;/span&gt; &lt;span&gt;main&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;init&lt;/span&gt;&lt;span&gt;:&lt;/span&gt; &lt;span&gt;std&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;process&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Init&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Minimal&lt;/span&gt;&lt;span&gt;)&lt;/span&gt; &lt;span&gt;!&lt;/span&gt;&lt;span&gt;void&lt;/span&gt; &lt;span&gt;{&lt;/span&gt;
    &lt;span&gt;var&lt;/span&gt; &lt;span&gt;debug_allocator&lt;/span&gt;&lt;span&gt;:&lt;/span&gt; &lt;span&gt;std&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;heap&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;DebugAllocator&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;)&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; &lt;span&gt;.&lt;/span&gt;&lt;span&gt;init&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;
    &lt;span&gt;const&lt;/span&gt; &lt;span&gt;gpa&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; &lt;span&gt;debug_allocator&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;allocator&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;

    &lt;span&gt;var&lt;/span&gt; &lt;span&gt;threaded&lt;/span&gt;&lt;span&gt;:&lt;/span&gt; &lt;span&gt;std&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Io&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Threaded&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; &lt;span&gt;.&lt;/span&gt;&lt;span&gt;init&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;gpa&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;.&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;
        &lt;span&gt;.&lt;/span&gt;&lt;span&gt;argv0&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; &lt;span&gt;.&lt;/span&gt;&lt;span&gt;init&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;init&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;args&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;
        &lt;span&gt;.&lt;/span&gt;&lt;span&gt;environ&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; &lt;span&gt;init&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;environ&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;
    &lt;span&gt;}&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;
    &lt;span&gt;defer&lt;/span&gt; &lt;span&gt;threaded&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;deinit&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;
    &lt;span&gt;const&lt;/span&gt; &lt;span&gt;io&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; &lt;span&gt;threaded&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;io&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;

    &lt;span&gt;return&lt;/span&gt; &lt;span&gt;app&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;io&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;
&lt;span&gt;}&lt;/span&gt;

&lt;span&gt;fn&lt;/span&gt; &lt;span&gt;app&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;io&lt;/span&gt;&lt;span&gt;:&lt;/span&gt; &lt;span&gt;std&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Io&lt;/span&gt;&lt;span&gt;)&lt;/span&gt; &lt;span&gt;!&lt;/span&gt;&lt;span&gt;void&lt;/span&gt; &lt;span&gt;{&lt;/span&gt;
    &lt;span&gt;try&lt;/span&gt; &lt;span&gt;std&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Io&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;File&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;stdout&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;writeStreamingAll&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;io&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;"Hello, World!&lt;/span&gt;&lt;span&gt;\n&lt;/span&gt;&lt;span&gt;"&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;
&lt;span&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$ strace ./hello_threaded
execve("./hello_threaded", ["./hello_threaded"], 0x7ffc1da88b20 /* 98 vars */) = 0
mmap(NULL, 262207, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f583f338000
arch_prctl(ARCH_SET_FS, 0x7f583f378018) = 0
prlimit64(0, RLIMIT_STACK, NULL, {rlim_cur=8192*1024, rlim_max=RLIM64_INFINITY}) = 0
prlimit64(0, RLIMIT_STACK, {rlim_cur=16384*1024, rlim_max=RLIM64_INFINITY}, NULL) = 0
sigaltstack({ss_sp=0x7f583f338000, ss_flags=0, ss_size=262144}, NULL) = 0
sched_getaffinity(0, 128, [0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31]) = 8
rt_sigaction(SIGIO, {sa_handler=0x1019d90, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x10328c0}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
rt_sigaction(SIGPIPE, {sa_handler=0x1019d90, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x10328c0}, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=0}, 8) = 0
writev(1, [{iov_base="Hello, World!\n", iov_len=14}], 1Hello, World!
) = 14
rt_sigaction(SIGIO, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x10328c0}, NULL, 8) = 0
rt_sigaction(SIGPIPE, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x10328c0}, NULL, 8) = 0
exit_group(0)                           = ?
+++ exited with 0 +++
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Swapping out only the I/O implementation:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;const&lt;/span&gt; &lt;span&gt;std&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; &lt;span&gt;@import&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;"std"&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;

&lt;span&gt;pub&lt;/span&gt; &lt;span&gt;fn&lt;/span&gt; &lt;span&gt;main&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;init&lt;/span&gt;&lt;span&gt;:&lt;/span&gt; &lt;span&gt;std&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;process&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Init&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Minimal&lt;/span&gt;&lt;span&gt;)&lt;/span&gt; &lt;span&gt;!&lt;/span&gt;&lt;span&gt;void&lt;/span&gt; &lt;span&gt;{&lt;/span&gt;
    &lt;span&gt;var&lt;/span&gt; &lt;span&gt;debug_allocator&lt;/span&gt;&lt;span&gt;:&lt;/span&gt; &lt;span&gt;std&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;heap&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;DebugAllocator&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;)&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; &lt;span&gt;.&lt;/span&gt;&lt;span&gt;init&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;
    &lt;span&gt;const&lt;/span&gt; &lt;span&gt;gpa&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; &lt;span&gt;debug_allocator&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;allocator&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;

    &lt;span&gt;var&lt;/span&gt; &lt;span&gt;evented&lt;/span&gt;&lt;span&gt;:&lt;/span&gt; &lt;span&gt;std&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Io&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Evented&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; &lt;span&gt;undefined&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;
    &lt;span&gt;try&lt;/span&gt; &lt;span&gt;evented&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;init&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;gpa&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;.&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;
        &lt;span&gt;.&lt;/span&gt;&lt;span&gt;argv0&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; &lt;span&gt;.&lt;/span&gt;&lt;span&gt;init&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;init&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;args&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;
        &lt;span&gt;.&lt;/span&gt;&lt;span&gt;environ&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; &lt;span&gt;init&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;environ&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;
        &lt;span&gt;.&lt;/span&gt;&lt;span&gt;backing_allocator_needs_mutex&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; &lt;span&gt;false&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;
    &lt;span&gt;}&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;
    &lt;span&gt;defer&lt;/span&gt; &lt;span&gt;evented&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;deinit&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;
    &lt;span&gt;const&lt;/span&gt; &lt;span&gt;io&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; &lt;span&gt;evented&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;io&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;

    &lt;span&gt;return&lt;/span&gt; &lt;span&gt;app&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;io&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;
&lt;span&gt;}&lt;/span&gt;

&lt;span&gt;fn&lt;/span&gt; &lt;span&gt;app&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;io&lt;/span&gt;&lt;span&gt;:&lt;/span&gt; &lt;span&gt;std&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Io&lt;/span&gt;&lt;span&gt;)&lt;/span&gt; &lt;span&gt;!&lt;/span&gt;&lt;span&gt;void&lt;/span&gt; &lt;span&gt;{&lt;/span&gt;
    &lt;span&gt;try&lt;/span&gt; &lt;span&gt;std&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Io&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;File&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;stdout&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;writeStreamingAll&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;io&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;"Hello, World!&lt;/span&gt;&lt;span&gt;\n&lt;/span&gt;&lt;span&gt;"&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;
&lt;span&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;execve("./hello_evented", ["./hello_evented"], 0x7fff368894f0 /* 98 vars */) = 0
mmap(NULL, 262215, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f70a4c28000
arch_prctl(ARCH_SET_FS, 0x7f70a4c68020) = 0
prlimit64(0, RLIMIT_STACK, NULL, {rlim_cur=8192*1024, rlim_max=RLIM64_INFINITY}) = 0
prlimit64(0, RLIMIT_STACK, {rlim_cur=16384*1024, rlim_max=RLIM64_INFINITY}, NULL) = 0
sigaltstack({ss_sp=0x7f70a4c28008, ss_flags=0, ss_size=262144}, NULL) = 0
sched_getaffinity(0, 128, [0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31]) = 8
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f70a4c27000
mmap(0x7f70a4c28000, 548864, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f70a4ba1000
io_uring_setup(64, {flags=IORING_SETUP_COOP_TASKRUN|IORING_SETUP_SINGLE_ISSUER, sq_thread_cpu=0, sq_thread_idle=1000, sq_entries=64, cq_entries=128, features=IORING_FEAT_SINGLE_MMAP|IORING_FEAT_NODROP|IORING_FEAT_SUBMIT_STABLE|IORING_FEAT_RW_CUR_POS|IORING_FEAT_CUR_PERSONALITY|IORING_FEAT_FAST_POLL|IORING_FEAT_POLL_32BITS|IORING_FEAT_SQPOLL_NONFIXED|IORING_FEAT_EXT_ARG|IORING_FEAT_NATIVE_WORKERS|IORING_FEAT_RSRC_TAGS|IORING_FEAT_CQE_SKIP|IORING_FEAT_LINKED_FILE|IORING_FEAT_REG_REG_RING|IORING_FEAT_RECVSEND_BUNDLE|IORING_FEAT_MIN_TIMEOUT|IORING_FEAT_RW_ATTR|IORING_FEAT_NO_IOWAIT, sq_off={head=0, tail=4, ring_mask=16, ring_entries=24, flags=36, dropped=32, array=2112, user_addr=0}, cq_off={head=8, tail=12, ring_mask=20, ring_entries=28, overflow=44, cqes=64, flags=40, user_addr=0}}) = 3
mmap(NULL, 2368, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_POPULATE, 3, 0) = 0x7f70a4ba0000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_POPULATE, 3, 0x10000000) = 0x7f70a4b9f000
io_uring_enter(3, 1, 1, IORING_ENTER_GETEVENTS, NULL, 8Hello, World!
) = 1
io_uring_enter(3, 1, 1, IORING_ENTER_GETEVENTS, NULL, 8) = 1
munmap(0x7f70a4b9f000, 4096)            = 0
munmap(0x7f70a4ba0000, 2368)            = 0
close(3)                                = 0
munmap(0x7f70a4ba1000, 548864)          = 0
exit_group(0)                           = ?
+++ exited with 0 +++
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Key point here being that the &lt;code&gt;app&lt;/code&gt; function is identical between those two snippets.&lt;/p&gt;&lt;p&gt;Moving beyond Hello World, the Zig compiler itself works fine using &lt;code&gt;std.Io.Evented&lt;/code&gt;, both with io_uring and with GCD, but as mentioned above, there is a not-yet-diagnosed performance degradation when doing so.&lt;/p&gt;&lt;p&gt;Happy hacking,&lt;/p&gt;&lt;p&gt;Andrew&lt;/p&gt;
&lt;/div&gt;
&lt;div id="2026-02-06" morss_own_score="2.7857142857142856" morss_score="65.98756613756615"&gt;
&lt;span&gt;February 06, 2026&lt;/span&gt;
&lt;h1&gt;&lt;a href="https://ziglang.org/devlog/2026/#2026-02-06"&gt;Two Package Management Workflow Enhancements
&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Author: Andrew Kelley&lt;/p&gt;&lt;p&gt;If you have a Zig project with dependencies, two big changes just landed which I think you will be interested to learn about.&lt;/p&gt;&lt;p&gt;Fetched packages are now stored &lt;em&gt;locally&lt;/em&gt; in the &lt;code&gt;zig-pkg&lt;/code&gt; directory of the project root (next to your &lt;code&gt;build.zig&lt;/code&gt; file).&lt;/p&gt;&lt;p&gt;For example here are a few results from &lt;a href="https://codeberg.org/awebo-chat/awebo"&gt;awebo&lt;/a&gt; after running &lt;code&gt;zig build&lt;/code&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;$ du -sh zig-pkg/*
13M    freetype-2.14.1-alzUkTyBqgBwke4Jsot997WYSpl207Ij9oO-2QOvGrOi
20K    opus-0.0.2-vuF-cMAkAADVsm707MYCtPmqmRs0gzg84Sz0qGbb5E3w
4.3M   pulseaudio-16.1.1-9-mk_62MZkNwBaFwiZ7ZVrYRIf_3dTqqJR5PbMRCJzSuLw
5.2M   uucode-0.1.0-ZZjBPvtWUACf5dqD_f9I37VGFsN24436CuceC5pTJ25n
728K   vaxis-0.5.1-BWNV_AxECQCj3p4Hcv4U3Yo1WMUJ7Z2FUj0UkpuJGxQQ
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;It is highly recommended to add this directory to the project-local source control ignore file (e.g. &lt;code&gt;.gitignore&lt;/code&gt;). However, by being outside of &lt;code&gt;.zig-cache&lt;/code&gt;, it provides the possibility of distributing self-contained source tarballs, which contain all dependencies and therefore can be used to build offline, or for archival purposes.&lt;/p&gt;&lt;p&gt;Meanwhile, an &lt;em&gt;additional&lt;/em&gt; copy of the dependency is cached globally. After filtering out all the unused files based on the &lt;code&gt;paths&lt;/code&gt; filter, the contents are recompressed:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;$ du -sh ~/.cache/zig/p/*
2.4M    freetype-2.14.1-alzUkTyBqgBwke4Jsot997WYSpl207Ij9oO-2QOvGrOi.tar.gz
4.0K    opus-0.0.2-vuF-cMAkAADVsm707MYCtPmqmRs0gzg84Sz0qGbb5E3w.tar.gz
636K    pulseaudio-16.1.1-9-mk_62MZkNwBaFwiZ7ZVrYRIf_3dTqqJR5PbMRCJzSuLw.tar.gz
880K    uucode-0.1.0-ZZjBPvtWUACf5dqD_f9I37VGFsN24436CuceC5pTJ25n.tar.gz
120K    vaxis-0.5.1-BWNV_BFECQBbXeTeFd48uTJRjD5a-KD6kPuKanzzVB01.tar.gz
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The motivation for this change is to make it easier to tinker. Go ahead and edit those files, see what happens. Swap out your package directory with a git clone. Grep your dependencies all together. Configure your IDE to auto-complete based on the &lt;code&gt;zig-pkg&lt;/code&gt; directory. &lt;a href="https://codeberg.org/awebo-chat/awebo/issues/61"&gt;Run baobab on your dependency tree&lt;/a&gt;. Furthermore, by having the global cache have compressed files instead makes it easier to share that cached data between computers. In the future, &lt;a href="https://github.com/ziglang/zig/issues/23236"&gt;it is planned to support peer-to-peer torrenting of dependency trees&lt;/a&gt;. By recompressing packages into a canonical form, this will allow peers to share Zig packages with minimal bandwidth. I love this idea because it simultaneously provides resilience to network outages, as well as a popularity contest. Find out which open source packages are popular based on number of seeders!&lt;/p&gt;&lt;p&gt;The second change here is the addition of the &lt;code&gt;--fork&lt;/code&gt; flag to &lt;code&gt;zig build&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;In retrospect, it seems so obvious, I don’t know why I didn’t think of it since the beginning. It looks like this:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;zig build --fork=[path]
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This is a &lt;strong&gt;project override&lt;/strong&gt; option. Given a path to a source checkout of a project, all packages matching that project across the entire dependency tree will be overridden.&lt;/p&gt;&lt;p&gt;Thanks to the fact that package content hashes include name and fingerprint, &lt;strong&gt;this resolves before the package is potentially fetched&lt;/strong&gt;.&lt;/p&gt;&lt;p&gt;This is an easy way to temporarily use one or more forks which are in entirely separate directories. You can iterate on your entire dependency tree until everything is working, while using comfortably the development environment and source control of the dependency projects.&lt;/p&gt;&lt;p&gt;The fact that it is a CLI flag makes it appropriately ephemeral. The moment you drop the flags, you’re back to using your pristine, fetched dependency tree.&lt;/p&gt;&lt;p&gt;If the project does not match, an error occurs, preventing confusion:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;$ zig build --fork=/home/andy/dev/mime
error: fork /home/andy/dev/mime matched no mime packages
$
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If the project does match, you get a reminder that you are using a fork, preventing confusion:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;$ zig build --fork=/home/andy/dev/dvui
info: fork /home/andy/dev/dvui matched 1 (dvui) packages
...
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This functionality is intended to enhance the workflow of dealing with ecosystem breakage. I already tried it a bit and found it to be quite pleasant to work with. The new workflow goes like this:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Fail to build from source due to ecosystem breakage.&lt;/li&gt;&lt;li&gt;Tinker with &lt;code&gt;--fork&lt;/code&gt; until your project works again. During this time you can use the actual upstream source control, test suite, &lt;code&gt;zig build test --watch -fincremental&lt;/code&gt;, etc.&lt;/li&gt;&lt;li&gt;Now you have a new option: be selfish and just keep working on your own stuff, or you can proceed to submit your patches upstream.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;…and you can probably skip the step where you switch your &lt;code&gt;build.zig.zon&lt;/code&gt; to your fork unless you expect upstream to take a long time to merge your fixes.&lt;/p&gt;
&lt;/div&gt;
&lt;div id="2026-02-03" morss_own_score="2.702888583218707" morss_score="68.84715520588823"&gt;
&lt;span&gt;February 03, 2026&lt;/span&gt;
&lt;h1&gt;&lt;a href="https://ziglang.org/devlog/2026/#2026-02-03"&gt;Bypassing Kernel32.dll for Fun and Nonprofit
&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Author: Andrew Kelley&lt;/p&gt;&lt;p&gt;The Windows operating system provides a large ABI surface area for doing things in the kernel. However, not all ABIs are created equally. As Casey Muratori points out in his lecture, &lt;a href="https://www.youtube.com/watch?v=5IUj1EZwpJY"&gt;The Only Unbreakable Law&lt;/a&gt;, the organizational structure of software development teams has a direct impact on the structure of the software they produce.&lt;/p&gt;&lt;p&gt;The DLLs on Windows are organized into a heirarchy, with some of the APIs being high-level wrappers around lower-level ones. For example, whenever you call functions of &lt;code&gt;kernel32.dll&lt;/code&gt;, ultimately, the actual work is done by &lt;code&gt;ntdll.dll&lt;/code&gt;. You can observe this directly by using ProcMon.exe and examining stack traces.&lt;/p&gt;&lt;p&gt;What we’ve learned empirically is that the ntdll APIs are generally well-engineered, reasonable, and powerful, but the kernel32 wrappers introduce unnecessary heap allocations, additional failure modes, unintentional CPU usage, and bloat.&lt;/p&gt;&lt;p&gt;This is why the Zig standard library policy is to &lt;a href="https://codeberg.org/ziglang/zig/issues/31131"&gt;Prefer the Native API over Win32&lt;/a&gt;. We’re not quite there yet - we have plenty of calls into kernel32 remaining - but we’ve taken great strides recently. I’ll give you two examples.&lt;/p&gt;&lt;h2&gt;Example 1: Entropy&lt;/h2&gt;&lt;p&gt;According to the official documentation, Windows does not have a straightforward way to get random bytes.&lt;/p&gt;&lt;p&gt;&lt;a href="https://github.com/rust-random/rand/issues/111"&gt;Many projects including Chromium, boringssl, Firefox, and Rust&lt;/a&gt; call &lt;code&gt;SystemFunction036&lt;/code&gt; from &lt;code&gt;advapi32.dll&lt;/code&gt; because it worked on versions older than Windows 8.&lt;/p&gt;&lt;p&gt;Unfortunately, starting with Windows 8, the first time you call this function, it dynamically loads &lt;code&gt;bcryptprimitives.dll&lt;/code&gt; and calls &lt;a href="https://learn.microsoft.com/en-us/windows/win32/seccng/processprng"&gt;ProcessPrng&lt;/a&gt;. If loading the DLL fails (for example due to an overloaded system, which we have observed on Zig CI several times), it returns error 38 (from a function that has &lt;code&gt;void&lt;/code&gt; return type and is documented to never fail).&lt;/p&gt;&lt;p&gt;The first thing &lt;code&gt;ProcessPrng&lt;/code&gt; does is heap allocate a small, constant number of bytes. If this fails it returns &lt;code&gt;NO_MEMORY&lt;/code&gt; in a &lt;code&gt;BOOL&lt;/code&gt; (documented behavior is to never fail, and always return &lt;code&gt;TRUE&lt;/code&gt;).&lt;/p&gt;&lt;p&gt;&lt;code&gt;bcryptprimitives.dll&lt;/code&gt; apparently also runs a test suite every time you load it.&lt;/p&gt;&lt;p&gt;All that &lt;code&gt;ProcessPrng&lt;/code&gt; is &lt;em&gt;really&lt;/em&gt; doing is &lt;code&gt;NtOpenFile&lt;/code&gt; on &lt;code&gt;"\\Device\\CNG"&lt;/code&gt; and reading 48 bytes with &lt;code&gt;NtDeviceIoControlFile&lt;/code&gt; to get a seed, and then initializing a per-CPU AES-based CSPRNG.&lt;/p&gt;&lt;p&gt;So the dependency on &lt;code&gt;bcryptprimitives.dll&lt;/code&gt; and &lt;code&gt;advapi32.dll&lt;/code&gt; can both be avoided, and the nondeterministic failure and latencies on first RNG read can also be avoided.&lt;/p&gt;&lt;h2&gt;Example 2: NtReadFile and NtWriteFile&lt;/h2&gt;&lt;p&gt;&lt;code&gt;ReadFile&lt;/code&gt; looks like this:&lt;/p&gt;&lt;pre&gt;&lt;code class="zig" morss_own_score="3.0" morss_score="10.5"&gt;&lt;span&gt;pub&lt;/span&gt; &lt;span&gt;extern&lt;/span&gt; &lt;span&gt;"kernel32"&lt;/span&gt; &lt;span&gt;fn&lt;/span&gt; &lt;span&gt;ReadFile&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;
    &lt;span&gt;hFile&lt;/span&gt;&lt;span&gt;:&lt;/span&gt; &lt;span&gt;HANDLE&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;
    &lt;span&gt;lpBuffer&lt;/span&gt;&lt;span&gt;:&lt;/span&gt; &lt;span&gt;LPVOID&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;
    &lt;span&gt;nNumberOfBytesToRead&lt;/span&gt;&lt;span&gt;:&lt;/span&gt; &lt;span&gt;DWORD&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;
    &lt;span&gt;lpNumberOfBytesRead&lt;/span&gt;&lt;span&gt;:&lt;/span&gt; &lt;span&gt;?&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;DWORD&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;
    &lt;span&gt;lpOverlapped&lt;/span&gt;&lt;span&gt;:&lt;/span&gt; &lt;span&gt;?&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;OVERLAPPED&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;
&lt;span&gt;)&lt;/span&gt; &lt;span&gt;callconv&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;winapi&lt;/span&gt;&lt;span&gt;)&lt;/span&gt; &lt;span&gt;BOOL&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;NtReadFile&lt;/code&gt; looks like this:&lt;/p&gt;&lt;pre&gt;&lt;code class="zig" morss_own_score="3.0" morss_score="16.5"&gt;&lt;span&gt;pub&lt;/span&gt; &lt;span&gt;extern&lt;/span&gt; &lt;span&gt;"ntdll"&lt;/span&gt; &lt;span&gt;fn&lt;/span&gt; &lt;span&gt;NtReadFile&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;
    &lt;span&gt;FileHandle&lt;/span&gt;&lt;span&gt;:&lt;/span&gt; &lt;span&gt;HANDLE&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;
    &lt;span&gt;Event&lt;/span&gt;&lt;span&gt;:&lt;/span&gt; &lt;span&gt;?&lt;/span&gt;&lt;span&gt;HANDLE&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;
    &lt;span&gt;ApcRoutine&lt;/span&gt;&lt;span&gt;:&lt;/span&gt; &lt;span&gt;?&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;const&lt;/span&gt; &lt;span&gt;IO_APC_ROUTINE&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;
    &lt;span&gt;ApcContext&lt;/span&gt;&lt;span&gt;:&lt;/span&gt; &lt;span&gt;?&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;anyopaque&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;
    &lt;span&gt;IoStatusBlock&lt;/span&gt;&lt;span&gt;:&lt;/span&gt; &lt;span&gt;*&lt;/span&gt;&lt;span&gt;IO_STATUS_BLOCK&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;
    &lt;span&gt;Buffer&lt;/span&gt;&lt;span&gt;:&lt;/span&gt; &lt;span&gt;*&lt;/span&gt;&lt;span&gt;anyopaque&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;
    &lt;span&gt;Length&lt;/span&gt;&lt;span&gt;:&lt;/span&gt; &lt;span&gt;ULONG&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;
    &lt;span&gt;ByteOffset&lt;/span&gt;&lt;span&gt;:&lt;/span&gt; &lt;span&gt;?&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;const&lt;/span&gt; &lt;span&gt;LARGE_INTEGER&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;
    &lt;span&gt;Key&lt;/span&gt;&lt;span&gt;:&lt;/span&gt; &lt;span&gt;?&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;const&lt;/span&gt; &lt;span&gt;ULONG&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;
&lt;span&gt;)&lt;/span&gt; &lt;span&gt;callconv&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;winapi&lt;/span&gt;&lt;span&gt;)&lt;/span&gt; &lt;span&gt;NTSTATUS&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As a reminder, &lt;em&gt;the above function is implemented by calling the below function&lt;/em&gt;.&lt;/p&gt;&lt;p&gt;Already we can see some nice things about using the lower level API. For instance, the &lt;em&gt;real&lt;/em&gt; API simply gives us the error code as the return value, while the kernel32 wrapper hides the status code somewhere, returns a &lt;code&gt;BOOL&lt;/code&gt; and then requires you to call &lt;code&gt;GetLastError&lt;/code&gt; to find out what went wrong. Imagine! Returning a value from a function 🌈&lt;/p&gt;&lt;p&gt;Furthermore, &lt;code&gt;OVERLAPPED&lt;/code&gt; is a fake type. The Windows kernel doesn’t actually know or care about it at all! The actual primitives here are events, APCs, and &lt;code&gt;IO_STATUS_BLOCK&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;If you have a synchronous file handle, then &lt;code&gt;Event&lt;/code&gt; and &lt;code&gt;ApcRoutine&lt;/code&gt; must be &lt;code&gt;null&lt;/code&gt;. You get the answer in the &lt;code&gt;IO_STATUS_BLOCK&lt;/code&gt; immediately. If you pass an APC routine here then some old bitrotted 32-bit code runs and you get garbage results.&lt;/p&gt;&lt;p&gt;On the other hand if you have an asynchronous file handle, then you need to either use an &lt;code&gt;Event&lt;/code&gt; or an &lt;code&gt;ApcRoutine&lt;/code&gt;. &lt;code&gt;kernel32.dll&lt;/code&gt; uses events, which means that it’s doing extra, unnecessary resource allocation and management just to read from a file. Instead, Zig now passes an APC routine and then calls &lt;code&gt;NtDelayExecution&lt;/code&gt;. This integrates seamlessly with cancelation, making it possible to cancel tasks while they perform file I/O, regardless of whether the file was opened in synchronous mode or asynchronous mode.&lt;/p&gt;&lt;p&gt;For a deeper dive into this topic, please refer to this issue:&lt;/p&gt;&lt;p&gt;&lt;a href="https://codeberg.org/ziglang/zig/issues/31131"&gt;Windows: Prefer the Native API over Win32&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div id="2026-01-31" morss_own_score="2.475982532751092" morss_score="28.633894388337364"&gt;
&lt;span&gt;January 31, 2026&lt;/span&gt;
&lt;h1&gt;&lt;a href="https://ziglang.org/devlog/2026/#2026-01-31"&gt;zig libc
&lt;/a&gt;&lt;/h1&gt;
&lt;p&gt;Author: Andrew Kelley&lt;/p&gt;&lt;p&gt;Over the past month or so, several enterprising contributors have taken an interest in the &lt;a href="https://codeberg.org/ziglang/zig/issues/30978"&gt;zig libc subproject&lt;/a&gt;. The idea here is to incrementally delete redundant code, by providing libc functions as Zig standard library wrappers rather than as vendored C source files. In many cases, these functions are one-to-one mappings, such as &lt;code&gt;memcpy&lt;/code&gt; or &lt;code&gt;atan2&lt;/code&gt;, or trivially wrap a generic function, like &lt;code&gt;strnlen&lt;/code&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;fn&lt;/span&gt; &lt;span&gt;strnlen&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;str&lt;/span&gt;&lt;span&gt;:&lt;/span&gt; &lt;span&gt;[&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;const&lt;/span&gt; &lt;span&gt;c_char&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;max&lt;/span&gt;&lt;span&gt;:&lt;/span&gt; &lt;span&gt;usize&lt;/span&gt;&lt;span&gt;)&lt;/span&gt; &lt;span&gt;callconv&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;c&lt;/span&gt;&lt;span&gt;)&lt;/span&gt; &lt;span&gt;usize&lt;/span&gt; &lt;span&gt;{&lt;/span&gt;
    &lt;span&gt;return&lt;/span&gt; &lt;span&gt;std&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;mem&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;findScalar&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;u8&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;@ptrCast&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;str&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;..&lt;/span&gt;&lt;span&gt;max&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt; &lt;span&gt;orelse&lt;/span&gt; &lt;span&gt;max&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;
&lt;span&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So far, roughly 250 C source files have been deleted from the Zig repository, with 2032 remaining.&lt;/p&gt;&lt;p&gt;With each function that makes the transition, Zig gains independence from third party projects and from the C programming language, compilation speed improves, Zig’s installation size is simplified and reduced, and user applications which statically link libc enjoy reduced binary size.&lt;/p&gt;&lt;p&gt;Additionally, a &lt;a href="https://codeberg.org/ziglang/zig/pulls/31037"&gt;recent enhancement&lt;/a&gt; now makes zig libc share the Zig Compilation Unit with other Zig code rather than being a separate static archive, linked together later. This is one of the advantages of Zig having an integrated compiler and linker. When the exported libc functions share the ZCU, redundant code is eliminated because functions can be optimized together. It’s kind of like enabling LTO (Link-Time Optimization) across the libc boundary, except it’s done properly in the frontend instead of too late, in the linker.&lt;/p&gt;&lt;p&gt;Furthermore, when this work is combined with the recent &lt;a href="https://codeberg.org/ziglang/zig/issues/30150"&gt;std.Io changes&lt;/a&gt;, there is potential for users to seamlessly control how libc performs I/O - for example forcing all calls to &lt;code&gt;read&lt;/code&gt; and &lt;code&gt;write&lt;/code&gt; to participate in an io_uring event loop, even though that code was not written with such use case in mind. Or, &lt;a href="https://codeberg.org/ziglang/zig/pulls/30788"&gt;resource leak detection&lt;/a&gt; could be enabled for third-party C code. For now this is only a vaporware idea which has not been experimented with, but the idea intrigues me.&lt;/p&gt;&lt;p&gt;Big thanks to Szabolcs Nagy for &lt;a href="https://wiki.musl-libc.org/libc-test.html"&gt;libc-test&lt;/a&gt;. This project has been a huge help in making sure that we don’t regress any math functions.&lt;/p&gt;&lt;p&gt;As a reminder to our users, now that Zig is transitioning to being the static libc provider, if you encounter issues with the musl, mingw-w64, or wasi-libc libc functionality provided by Zig, &lt;strong&gt;please file bug reports in Zig first&lt;/strong&gt; so we don’t annoy maintainers for bugs that are in Zig, and no longer vendored by independent libc implementation projects.&lt;/p&gt;&lt;p&gt;The very same day I sat at home writing this devlog like a coward, less than five miles away, &lt;a href="https://www.kptv.com/2026/01/31/live-labor-unions-rally-march-portland-ice-facility-protest/"&gt;armed forces who are in my city against the will of our elected officials shot tear gas, unprovoked, at peaceful protestors&lt;/a&gt;. Next time I hope to have the courage to join my neighbors, and I hope to not get shot like &lt;a href="https://en.wikipedia.org/wiki/Killing_of_Alex_Pretti"&gt;Alex Pretti&lt;/a&gt; and &lt;a href="https://en.wikipedia.org/wiki/Killing_of_Ren%C3%A9e_Good"&gt;Renée Good&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
</ns0:encoded></item><item><title>Voxel Space</title><link>https://s-macke.github.io/VoxelSpace/</link><pubDate>Sat, 30 May 2026 14:25:50 +0000</pubDate><comments>https://news.ycombinator.com/item?id=48336564</comments><description>&lt;a href="https://news.ycombinator.com/item?id=48336564"&gt;Comments&lt;/a&gt;</description><ns0:encoded xmlns:ns0="http://purl.org/rss/1.0/modules/content/">&lt;div class="container-lg px-3 my-5 markdown-body" morss_own_score="5.048665620094191" morss_score="141.38707877926205"&gt;
&lt;h1&gt;&lt;a href="https://s-macke.github.io/VoxelSpace/"&gt;VoxelSpace&lt;/a&gt;&lt;/h1&gt;
&lt;h1&gt;Voxel Space&lt;/h1&gt;
&lt;p&gt;&lt;img src="https://s-macke.github.io/VoxelSpace/images/webdemo.gif"&gt;&lt;/p&gt;
&lt;h1&gt;&lt;strong&gt;&lt;a href="https://s-macke.github.io/VoxelSpace/VoxelSpace.html"&gt;Web Demo of the Voxel Space Engine&lt;/a&gt;&lt;/strong&gt;&lt;/h1&gt;
&lt;h2&gt;History&lt;/h2&gt;
&lt;p&gt;Let us go back to the year 1992. The CPUs were 1000 times slower than today and the acceleration via a GPU was unknown or unaffordable. 3D games were calculated exclusively on the CPU and the rendering engine rendered filled polygons with a single color.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://s-macke.github.io/VoxelSpace/images/gunship2000-1991.gif"&gt;
&lt;em&gt;Game Gunship 2000 published by MicroProse in 1991&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;It was during that year &lt;a href="http://www.novalogic.com/"&gt;NovaLogic&lt;/a&gt; published the game &lt;a href="https://en.wikipedia.org/wiki/Comanche_(video_game_series)"&gt;Comanche&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://s-macke.github.io/VoxelSpace/images/comanche-1992.gif"&gt;
&lt;em&gt;Game Comanche published by NovaLogic in 1992&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;The graphics were breathtaking for the time being and in my opinion 3 years ahead of its time. You see many more details such as textures on mountains and valleys, and for the first time a neat shading and even shadows. Sure, it’s pixelated, but all games in those years were pixelated.&lt;/p&gt;
&lt;h2&gt;Render algorithm&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Comanche_(video_game_series)"&gt;Comanche&lt;/a&gt; uses a technique called &lt;a href="https://en.wikipedia.org/wiki/Voxel_Space"&gt;Voxel Space&lt;/a&gt;, which is based on the same ideas like &lt;a href="https://en.wikipedia.org/wiki/Ray_casting"&gt;ray casting&lt;/a&gt;. Hence the Voxel Space engine is a 2.5D engine, it doesn’t have all the levels of freedom that a regular 3D engine offers.&lt;/p&gt;
&lt;h3&gt;Height map and color map&lt;/h3&gt;
&lt;p&gt;The easiest way to represent a terrain is through a height map and color map. For the game Comanche a 1024 * 1024 one byte height map and a 1024 * 1024 one byte color map is used which you can download on this site. These maps are periodic:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://s-macke.github.io/VoxelSpace/images/periodicmap.gif"&gt;&lt;/p&gt;
&lt;p&gt;Such maps limit the terrain to “one height per position on the map” - Complex geometries such as buildings or trees are not possible to represent. However, a great advantage of the colormap is, that it already contains the shading and shadows. The Voxel Space engine just takes the color and doesn’t have to compute illumination during the render process.&lt;/p&gt;
&lt;h3&gt;Basic algorithm&lt;/h3&gt;
&lt;p&gt;For a 3D engine the rendering algorithm is amazingly simple. The Voxel Space engine rasters the height and color map and draws vertical lines. The following figure demonstrate this technique.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://s-macke.github.io/VoxelSpace/images/linebyline.gif"&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Clear Screen.&lt;/li&gt;
&lt;li&gt;To guarantee occlusion start from the back and render to the front. This is called painter algorithm.&lt;/li&gt;
&lt;li&gt;Determine the line on the map, which corresponds to the same optical distance from the observer. Consider the field of view and the &lt;a href="https://en.wikipedia.org/wiki/3D_projection"&gt;perspective projection&lt;/a&gt; (Objects are smaller farther away)&lt;/li&gt;
&lt;li&gt;Raster the line so that it matches the number of columns of the screen.&lt;/li&gt;
&lt;li&gt;Retrieve the height and color from the 2D maps corresponding of the segment of the line.&lt;/li&gt;
&lt;li&gt;Perform the &lt;a href="https://en.wikipedia.org/wiki/3D_projection"&gt;perspective projection&lt;/a&gt; for the height coordinate.&lt;/li&gt;
&lt;li&gt;Draw a vertical line with the corresponding color with the height retrieved from the perspective projection.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The core algorithm contains in its simplest form only a few lines of code (python syntax):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;def&lt;/span&gt; &lt;span&gt;Render&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;p&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;height&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;horizon&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;scale_height&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;distance&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;screen_width&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;screen_height&lt;/span&gt;&lt;span&gt;):&lt;/span&gt;
    &lt;span&gt;# Draw from back to the front (high z coordinate to low z coordinate)
&lt;/span&gt;    &lt;span&gt;for&lt;/span&gt; &lt;span&gt;z&lt;/span&gt; &lt;span&gt;in&lt;/span&gt; &lt;span&gt;range&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;distance&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;1&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;-&lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;):&lt;/span&gt;
        &lt;span&gt;# Find line on map. This calculation corresponds to a field of view of 90°
&lt;/span&gt;        &lt;span&gt;pleft&lt;/span&gt;  &lt;span&gt;=&lt;/span&gt; &lt;span&gt;Point&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;-&lt;/span&gt;&lt;span&gt;z&lt;/span&gt; &lt;span&gt;+&lt;/span&gt; &lt;span&gt;p&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;x&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;-&lt;/span&gt;&lt;span&gt;z&lt;/span&gt; &lt;span&gt;+&lt;/span&gt; &lt;span&gt;p&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;y&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;
        &lt;span&gt;pright&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; &lt;span&gt;Point&lt;/span&gt;&lt;span&gt;(&lt;/span&gt; &lt;span&gt;z&lt;/span&gt; &lt;span&gt;+&lt;/span&gt; &lt;span&gt;p&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;x&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;-&lt;/span&gt;&lt;span&gt;z&lt;/span&gt; &lt;span&gt;+&lt;/span&gt; &lt;span&gt;p&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;y&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;
        &lt;span&gt;# segment the line
&lt;/span&gt;        &lt;span&gt;dx&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; &lt;span&gt;(&lt;/span&gt;&lt;span&gt;pright&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;x&lt;/span&gt; &lt;span&gt;-&lt;/span&gt; &lt;span&gt;pleft&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;x&lt;/span&gt;&lt;span&gt;)&lt;/span&gt; &lt;span&gt;/&lt;/span&gt; &lt;span&gt;screen_width&lt;/span&gt;
        &lt;span&gt;# Raster line and draw a vertical line for each segment
&lt;/span&gt;        &lt;span&gt;for&lt;/span&gt; &lt;span&gt;i&lt;/span&gt; &lt;span&gt;in&lt;/span&gt; &lt;span&gt;range&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;screen_width&lt;/span&gt;&lt;span&gt;):&lt;/span&gt;
            &lt;span&gt;height_on_screen&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; &lt;span&gt;(&lt;/span&gt;&lt;span&gt;height&lt;/span&gt; &lt;span&gt;-&lt;/span&gt; &lt;span&gt;heightmap&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;pleft&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;x&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;pleft&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;y&lt;/span&gt;&lt;span&gt;])&lt;/span&gt; &lt;span&gt;/&lt;/span&gt; &lt;span&gt;z&lt;/span&gt; &lt;span&gt;*&lt;/span&gt; &lt;span&gt;scale_height&lt;/span&gt;&lt;span&gt;.&lt;/span&gt; &lt;span&gt;+&lt;/span&gt; &lt;span&gt;horizon&lt;/span&gt;
            &lt;span&gt;DrawVerticalLine&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;i&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;height_on_screen&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;screen_height&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;colormap&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;pleft&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;x&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;pleft&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;y&lt;/span&gt;&lt;span&gt;])&lt;/span&gt;
            &lt;span&gt;pleft&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;x&lt;/span&gt; &lt;span&gt;+=&lt;/span&gt; &lt;span&gt;dx&lt;/span&gt;

&lt;span&gt;# Call the render function with the camera parameters:
# position, height, horizon line position,
# scaling factor for the height, the largest distance, 
# screen width and the screen height parameter
&lt;/span&gt;&lt;span&gt;Render&lt;/span&gt;&lt;span&gt;(&lt;/span&gt; &lt;span&gt;Point&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;0&lt;/span&gt;&lt;span&gt;),&lt;/span&gt; &lt;span&gt;50&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;120&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;120&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;300&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;800&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;600&lt;/span&gt; &lt;span&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Add rotation&lt;/h3&gt;
&lt;p&gt;With the algorithm above we can only view to the north. A different angle needs a few more lines of code to rotate the coordinates.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://s-macke.github.io/VoxelSpace/images/rotate.gif"&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;def&lt;/span&gt; &lt;span&gt;Render&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;p&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;phi&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;height&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;horizon&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;scale_height&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;distance&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;screen_width&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;screen_height&lt;/span&gt;&lt;span&gt;):&lt;/span&gt;
    &lt;span&gt;# precalculate viewing angle parameters
&lt;/span&gt;    &lt;span&gt;var&lt;/span&gt; &lt;span&gt;sinphi&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; &lt;span&gt;math&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;sin&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;phi&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;
    &lt;span&gt;var&lt;/span&gt; &lt;span&gt;cosphi&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; &lt;span&gt;math&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;cos&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;phi&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;

    &lt;span&gt;# Draw from back to the front (high z coordinate to low z coordinate)
&lt;/span&gt;    &lt;span&gt;for&lt;/span&gt; &lt;span&gt;z&lt;/span&gt; &lt;span&gt;in&lt;/span&gt; &lt;span&gt;range&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;distance&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;1&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;-&lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;):&lt;/span&gt;

        &lt;span&gt;# Find line on map. This calculation corresponds to a field of view of 90°
&lt;/span&gt;        &lt;span&gt;pleft&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; &lt;span&gt;Point&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;
            &lt;span&gt;(&lt;/span&gt;&lt;span&gt;-&lt;/span&gt;&lt;span&gt;cosphi&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;z&lt;/span&gt; &lt;span&gt;-&lt;/span&gt; &lt;span&gt;sinphi&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;z&lt;/span&gt;&lt;span&gt;)&lt;/span&gt; &lt;span&gt;+&lt;/span&gt; &lt;span&gt;p&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;x&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;
            &lt;span&gt;(&lt;/span&gt; &lt;span&gt;sinphi&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;z&lt;/span&gt; &lt;span&gt;-&lt;/span&gt; &lt;span&gt;cosphi&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;z&lt;/span&gt;&lt;span&gt;)&lt;/span&gt; &lt;span&gt;+&lt;/span&gt; &lt;span&gt;p&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;y&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;
        &lt;span&gt;pright&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; &lt;span&gt;Point&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;
            &lt;span&gt;(&lt;/span&gt; &lt;span&gt;cosphi&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;z&lt;/span&gt; &lt;span&gt;-&lt;/span&gt; &lt;span&gt;sinphi&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;z&lt;/span&gt;&lt;span&gt;)&lt;/span&gt; &lt;span&gt;+&lt;/span&gt; &lt;span&gt;p&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;x&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;
            &lt;span&gt;(&lt;/span&gt;&lt;span&gt;-&lt;/span&gt;&lt;span&gt;sinphi&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;z&lt;/span&gt; &lt;span&gt;-&lt;/span&gt; &lt;span&gt;cosphi&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;z&lt;/span&gt;&lt;span&gt;)&lt;/span&gt; &lt;span&gt;+&lt;/span&gt; &lt;span&gt;p&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;y&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;
        
        &lt;span&gt;# segment the line
&lt;/span&gt;        &lt;span&gt;dx&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; &lt;span&gt;(&lt;/span&gt;&lt;span&gt;pright&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;x&lt;/span&gt; &lt;span&gt;-&lt;/span&gt; &lt;span&gt;pleft&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;x&lt;/span&gt;&lt;span&gt;)&lt;/span&gt; &lt;span&gt;/&lt;/span&gt; &lt;span&gt;screen_width&lt;/span&gt;
        &lt;span&gt;dy&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; &lt;span&gt;(&lt;/span&gt;&lt;span&gt;pright&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;y&lt;/span&gt; &lt;span&gt;-&lt;/span&gt; &lt;span&gt;pleft&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;y&lt;/span&gt;&lt;span&gt;)&lt;/span&gt; &lt;span&gt;/&lt;/span&gt; &lt;span&gt;screen_width&lt;/span&gt;

        &lt;span&gt;# Raster line and draw a vertical line for each segment
&lt;/span&gt;        &lt;span&gt;for&lt;/span&gt; &lt;span&gt;i&lt;/span&gt; &lt;span&gt;in&lt;/span&gt; &lt;span&gt;range&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;screen_width&lt;/span&gt;&lt;span&gt;):&lt;/span&gt;
            &lt;span&gt;height_on_screen&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; &lt;span&gt;(&lt;/span&gt;&lt;span&gt;height&lt;/span&gt; &lt;span&gt;-&lt;/span&gt; &lt;span&gt;heightmap&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;pleft&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;x&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;pleft&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;y&lt;/span&gt;&lt;span&gt;])&lt;/span&gt; &lt;span&gt;/&lt;/span&gt; &lt;span&gt;z&lt;/span&gt; &lt;span&gt;*&lt;/span&gt; &lt;span&gt;scale_height&lt;/span&gt;&lt;span&gt;.&lt;/span&gt; &lt;span&gt;+&lt;/span&gt; &lt;span&gt;horizon&lt;/span&gt;
            &lt;span&gt;DrawVerticalLine&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;i&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;height_on_screen&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;screen_height&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;colormap&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;pleft&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;x&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;pleft&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;y&lt;/span&gt;&lt;span&gt;])&lt;/span&gt;
            &lt;span&gt;pleft&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;x&lt;/span&gt; &lt;span&gt;+=&lt;/span&gt; &lt;span&gt;dx&lt;/span&gt;
            &lt;span&gt;pleft&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;y&lt;/span&gt; &lt;span&gt;+=&lt;/span&gt; &lt;span&gt;dy&lt;/span&gt;

&lt;span&gt;# Call the render function with the camera parameters:
# position, viewing angle, height, horizon line position, 
# scaling factor for the height, the largest distance, 
# screen width and the screen height parameter
&lt;/span&gt;&lt;span&gt;Render&lt;/span&gt;&lt;span&gt;(&lt;/span&gt; &lt;span&gt;Point&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;0&lt;/span&gt;&lt;span&gt;),&lt;/span&gt; &lt;span&gt;0&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;50&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;120&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;120&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;300&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;800&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;600&lt;/span&gt; &lt;span&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;More performance&lt;/h3&gt;
&lt;p&gt;There are of course a lot of tricks to achieve higher performance.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Instead of drawing from back to the front we can draw from front to back. The advantage is, the we don’t have to draw lines to the bottom of the screen every time because of occlusion. However, to guarantee occlusion we need an additional y-buffer. For every column, the highest y position is stored. Because we are drawing from the front to back, the visible part of the next line can only be larger then the highest line previously drawn.&lt;/li&gt;
&lt;li&gt;Level of Detail. Render more details in front but less details far away.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src="https://s-macke.github.io/VoxelSpace/images/fronttoback.gif"&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;def&lt;/span&gt; &lt;span&gt;Render&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;p&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;phi&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;height&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;horizon&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;scale_height&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;distance&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;screen_width&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;screen_height&lt;/span&gt;&lt;span&gt;):&lt;/span&gt;
    &lt;span&gt;# precalculate viewing angle parameters
&lt;/span&gt;    &lt;span&gt;var&lt;/span&gt; &lt;span&gt;sinphi&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; &lt;span&gt;math&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;sin&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;phi&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;
    &lt;span&gt;var&lt;/span&gt; &lt;span&gt;cosphi&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; &lt;span&gt;math&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;cos&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;phi&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;
    
    &lt;span&gt;# initialize visibility array. Y position for each column on screen 
&lt;/span&gt;    &lt;span&gt;ybuffer&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; &lt;span&gt;np&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;zeros&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;screen_width&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;
    &lt;span&gt;for&lt;/span&gt; &lt;span&gt;i&lt;/span&gt; &lt;span&gt;in&lt;/span&gt; &lt;span&gt;range&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;screen_width&lt;/span&gt;&lt;span&gt;):&lt;/span&gt;
        &lt;span&gt;ybuffer&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;i&lt;/span&gt;&lt;span&gt;]&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; &lt;span&gt;screen_height&lt;/span&gt;

    &lt;span&gt;# Draw from front to the back (low z coordinate to high z coordinate)
&lt;/span&gt;    &lt;span&gt;dz&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; &lt;span&gt;1.&lt;/span&gt;
    &lt;span&gt;z&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; &lt;span&gt;1.&lt;/span&gt;
    &lt;span&gt;while&lt;/span&gt; &lt;span&gt;z&lt;/span&gt; &lt;span&gt;&amp;lt;&lt;/span&gt; &lt;span&gt;distance&lt;/span&gt;
        &lt;span&gt;# Find line on map. This calculation corresponds to a field of view of 90°
&lt;/span&gt;        &lt;span&gt;pleft&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; &lt;span&gt;Point&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;
            &lt;span&gt;(&lt;/span&gt;&lt;span&gt;-&lt;/span&gt;&lt;span&gt;cosphi&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;z&lt;/span&gt; &lt;span&gt;-&lt;/span&gt; &lt;span&gt;sinphi&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;z&lt;/span&gt;&lt;span&gt;)&lt;/span&gt; &lt;span&gt;+&lt;/span&gt; &lt;span&gt;p&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;x&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;
            &lt;span&gt;(&lt;/span&gt; &lt;span&gt;sinphi&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;z&lt;/span&gt; &lt;span&gt;-&lt;/span&gt; &lt;span&gt;cosphi&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;z&lt;/span&gt;&lt;span&gt;)&lt;/span&gt; &lt;span&gt;+&lt;/span&gt; &lt;span&gt;p&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;y&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;
        &lt;span&gt;pright&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; &lt;span&gt;Point&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;
            &lt;span&gt;(&lt;/span&gt; &lt;span&gt;cosphi&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;z&lt;/span&gt; &lt;span&gt;-&lt;/span&gt; &lt;span&gt;sinphi&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;z&lt;/span&gt;&lt;span&gt;)&lt;/span&gt; &lt;span&gt;+&lt;/span&gt; &lt;span&gt;p&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;x&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;
            &lt;span&gt;(&lt;/span&gt;&lt;span&gt;-&lt;/span&gt;&lt;span&gt;sinphi&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;z&lt;/span&gt; &lt;span&gt;-&lt;/span&gt; &lt;span&gt;cosphi&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;z&lt;/span&gt;&lt;span&gt;)&lt;/span&gt; &lt;span&gt;+&lt;/span&gt; &lt;span&gt;p&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;y&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;

        &lt;span&gt;# segment the line
&lt;/span&gt;        &lt;span&gt;dx&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; &lt;span&gt;(&lt;/span&gt;&lt;span&gt;pright&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;x&lt;/span&gt; &lt;span&gt;-&lt;/span&gt; &lt;span&gt;pleft&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;x&lt;/span&gt;&lt;span&gt;)&lt;/span&gt; &lt;span&gt;/&lt;/span&gt; &lt;span&gt;screen_width&lt;/span&gt;
        &lt;span&gt;dy&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; &lt;span&gt;(&lt;/span&gt;&lt;span&gt;pright&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;y&lt;/span&gt; &lt;span&gt;-&lt;/span&gt; &lt;span&gt;pleft&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;y&lt;/span&gt;&lt;span&gt;)&lt;/span&gt; &lt;span&gt;/&lt;/span&gt; &lt;span&gt;screen_width&lt;/span&gt;

        &lt;span&gt;# Raster line and draw a vertical line for each segment
&lt;/span&gt;        &lt;span&gt;for&lt;/span&gt; &lt;span&gt;i&lt;/span&gt; &lt;span&gt;in&lt;/span&gt; &lt;span&gt;range&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;screen_width&lt;/span&gt;&lt;span&gt;):&lt;/span&gt;
            &lt;span&gt;height_on_screen&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; &lt;span&gt;(&lt;/span&gt;&lt;span&gt;height&lt;/span&gt; &lt;span&gt;-&lt;/span&gt; &lt;span&gt;heightmap&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;pleft&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;x&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;pleft&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;y&lt;/span&gt;&lt;span&gt;])&lt;/span&gt; &lt;span&gt;/&lt;/span&gt; &lt;span&gt;z&lt;/span&gt; &lt;span&gt;*&lt;/span&gt; &lt;span&gt;scale_height&lt;/span&gt;&lt;span&gt;.&lt;/span&gt; &lt;span&gt;+&lt;/span&gt; &lt;span&gt;horizon&lt;/span&gt;
            &lt;span&gt;DrawVerticalLine&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;i&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;height_on_screen&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;ybuffer&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;i&lt;/span&gt;&lt;span&gt;],&lt;/span&gt; &lt;span&gt;colormap&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;pleft&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;x&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;pleft&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;y&lt;/span&gt;&lt;span&gt;])&lt;/span&gt;
            &lt;span&gt;if&lt;/span&gt; &lt;span&gt;height_on_screen&lt;/span&gt; &lt;span&gt;&amp;lt;&lt;/span&gt; &lt;span&gt;ybuffer&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;i&lt;/span&gt;&lt;span&gt;]:&lt;/span&gt;
                &lt;span&gt;ybuffer&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;i&lt;/span&gt;&lt;span&gt;]&lt;/span&gt; &lt;span&gt;=&lt;/span&gt; &lt;span&gt;height_on_screen&lt;/span&gt;
            &lt;span&gt;pleft&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;x&lt;/span&gt; &lt;span&gt;+=&lt;/span&gt; &lt;span&gt;dx&lt;/span&gt;
            &lt;span&gt;pleft&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;y&lt;/span&gt; &lt;span&gt;+=&lt;/span&gt; &lt;span&gt;dy&lt;/span&gt;

        &lt;span&gt;# Go to next line and increase step size when you are far away
&lt;/span&gt;        &lt;span&gt;z&lt;/span&gt; &lt;span&gt;+=&lt;/span&gt; &lt;span&gt;dz&lt;/span&gt;
        &lt;span&gt;dz&lt;/span&gt; &lt;span&gt;+=&lt;/span&gt; &lt;span&gt;0.2&lt;/span&gt;

&lt;span&gt;# Call the render function with the camera parameters:
# position, viewing angle, height, horizon line position, 
# scaling factor for the height, the largest distance, 
# screen width and the screen height parameter
&lt;/span&gt;&lt;span&gt;Render&lt;/span&gt;&lt;span&gt;(&lt;/span&gt; &lt;span&gt;Point&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;0&lt;/span&gt;&lt;span&gt;),&lt;/span&gt; &lt;span&gt;0&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;50&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;120&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;120&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;300&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;800&lt;/span&gt;&lt;span&gt;,&lt;/span&gt; &lt;span&gt;600&lt;/span&gt; &lt;span&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Links&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://s-macke.github.io/VoxelSpace/VoxelSpace.html"&gt;Web Project demo&lt;/a&gt; page&lt;/p&gt;
&lt;p&gt;&lt;a href="https://web.archive.org/web/20131113094653/http://www.codermind.com/articles/Voxel-terrain-engine-building-the-terrain.html"&gt;Voxel terrain engine - an introduction&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.simulationcorner.net"&gt;Personal website&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Maps&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://s-macke.github.io/VoxelSpace/maps/C1W.png"&gt;color&lt;/a&gt;,
&lt;a href="https://s-macke.github.io/VoxelSpace/maps/D1.png"&gt;height&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://s-macke.github.io/VoxelSpace/images/thumbnails/C1W.png"&gt;
&lt;img src="https://s-macke.github.io/VoxelSpace/images/thumbnails/D1.png"&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://s-macke.github.io/VoxelSpace/maps/C2W.png"&gt;color&lt;/a&gt;,
&lt;a href="https://s-macke.github.io/VoxelSpace/maps/D2.png"&gt;height&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://s-macke.github.io/VoxelSpace/images/thumbnails/C2W.png"&gt;
&lt;img src="https://s-macke.github.io/VoxelSpace/images/thumbnails/D2.png"&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://s-macke.github.io/VoxelSpace/maps/C3.png"&gt;color&lt;/a&gt;,
&lt;a href="https://s-macke.github.io/VoxelSpace/maps/D3.png"&gt;height&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://s-macke.github.io/VoxelSpace/images/thumbnails/C3.png"&gt;
&lt;img src="https://s-macke.github.io/VoxelSpace/images/thumbnails/D3.png"&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://s-macke.github.io/VoxelSpace/maps/C4.png"&gt;color&lt;/a&gt;,
&lt;a href="https://s-macke.github.io/VoxelSpace/maps/D4.png"&gt;height&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://s-macke.github.io/VoxelSpace/images/thumbnails/C4.png"&gt;
&lt;img src="https://s-macke.github.io/VoxelSpace/images/thumbnails/D4.png"&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://s-macke.github.io/VoxelSpace/maps/C5W.png"&gt;color&lt;/a&gt;,
&lt;a href="https://s-macke.github.io/VoxelSpace/maps/D5.png"&gt;height&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://s-macke.github.io/VoxelSpace/images/thumbnails/C5W.png"&gt;
&lt;img src="https://s-macke.github.io/VoxelSpace/images/thumbnails/D5.png"&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://s-macke.github.io/VoxelSpace/maps/C6W.png"&gt;color&lt;/a&gt;,
&lt;a href="https://s-macke.github.io/VoxelSpace/maps/D6.png"&gt;height&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://s-macke.github.io/VoxelSpace/images/thumbnails/C6W.png"&gt;
&lt;img src="https://s-macke.github.io/VoxelSpace/images/thumbnails/D6.png"&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://s-macke.github.io/VoxelSpace/maps/C7W.png"&gt;color&lt;/a&gt;,
&lt;a href="https://s-macke.github.io/VoxelSpace/maps/D7.png"&gt;height&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://s-macke.github.io/VoxelSpace/images/thumbnails/C7W.png"&gt;
&lt;img src="https://s-macke.github.io/VoxelSpace/images/thumbnails/D7.png"&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://s-macke.github.io/VoxelSpace/maps/C8.png"&gt;color&lt;/a&gt;,
&lt;a href="https://s-macke.github.io/VoxelSpace/maps/D6.png"&gt;height&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://s-macke.github.io/VoxelSpace/images/thumbnails/C8.png"&gt;
&lt;img src="https://s-macke.github.io/VoxelSpace/images/thumbnails/D6.png"&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://s-macke.github.io/VoxelSpace/maps/C9W.png"&gt;color&lt;/a&gt;,
&lt;a href="https://s-macke.github.io/VoxelSpace/maps/D9.png"&gt;height&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://s-macke.github.io/VoxelSpace/images/thumbnails/C9W.png"&gt;
&lt;img src="https://s-macke.github.io/VoxelSpace/images/thumbnails/D9.png"&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://s-macke.github.io/VoxelSpace/maps/C10W.png"&gt;color&lt;/a&gt;,
&lt;a href="https://s-macke.github.io/VoxelSpace/maps/D10.png"&gt;height&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://s-macke.github.io/VoxelSpace/images/thumbnails/C10W.png"&gt;
&lt;img src="https://s-macke.github.io/VoxelSpace/images/thumbnails/D10.png"&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://s-macke.github.io/VoxelSpace/maps/C11W.png"&gt;color&lt;/a&gt;,
&lt;a href="https://s-macke.github.io/VoxelSpace/maps/D11.png"&gt;height&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://s-macke.github.io/VoxelSpace/images/thumbnails/C11W.png"&gt;
&lt;img src="https://s-macke.github.io/VoxelSpace/images/thumbnails/D11.png"&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://s-macke.github.io/VoxelSpace/maps/C12W.png"&gt;color&lt;/a&gt;,
&lt;a href="https://s-macke.github.io/VoxelSpace/maps/D11.png"&gt;height&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://s-macke.github.io/VoxelSpace/images/thumbnails/C12W.png"&gt;
&lt;img src="https://s-macke.github.io/VoxelSpace/images/thumbnails/D11.png"&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://s-macke.github.io/VoxelSpace/maps/C13.png"&gt;color&lt;/a&gt;,
&lt;a href="https://s-macke.github.io/VoxelSpace/maps/D13.png"&gt;height&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://s-macke.github.io/VoxelSpace/images/thumbnails/C13.png"&gt;
&lt;img src="https://s-macke.github.io/VoxelSpace/images/thumbnails/D13.png"&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://s-macke.github.io/VoxelSpace/maps/C14.png"&gt;color&lt;/a&gt;,
&lt;a href="https://s-macke.github.io/VoxelSpace/maps/D14.png"&gt;height&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://s-macke.github.io/VoxelSpace/images/thumbnails/C14.png"&gt;
&lt;img src="https://s-macke.github.io/VoxelSpace/images/thumbnails/D14.png"&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://s-macke.github.io/VoxelSpace/maps/C14W.png"&gt;color&lt;/a&gt;,
&lt;a href="https://s-macke.github.io/VoxelSpace/maps/D14.png"&gt;height&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://s-macke.github.io/VoxelSpace/images/thumbnails/C14W.png"&gt;
&lt;img src="https://s-macke.github.io/VoxelSpace/images/thumbnails/D14.png"&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://s-macke.github.io/VoxelSpace/maps/C15.png"&gt;color&lt;/a&gt;,
&lt;a href="https://s-macke.github.io/VoxelSpace/maps/D15.png"&gt;height&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://s-macke.github.io/VoxelSpace/images/thumbnails/C15.png"&gt;
&lt;img src="https://s-macke.github.io/VoxelSpace/images/thumbnails/D15.png"&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://s-macke.github.io/VoxelSpace/maps/C16W.png"&gt;color&lt;/a&gt;,
&lt;a href="https://s-macke.github.io/VoxelSpace/maps/D16.png"&gt;height&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://s-macke.github.io/VoxelSpace/images/thumbnails/C16W.png"&gt;
&lt;img src="https://s-macke.github.io/VoxelSpace/images/thumbnails/D16.png"&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://s-macke.github.io/VoxelSpace/maps/C17W.png"&gt;color&lt;/a&gt;,
&lt;a href="https://s-macke.github.io/VoxelSpace/maps/D17.png"&gt;height&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://s-macke.github.io/VoxelSpace/images/thumbnails/C17W.png"&gt;
&lt;img src="https://s-macke.github.io/VoxelSpace/images/thumbnails/D17.png"&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://s-macke.github.io/VoxelSpace/maps/C18W.png"&gt;color&lt;/a&gt;,
&lt;a href="https://s-macke.github.io/VoxelSpace/maps/D18.png"&gt;height&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://s-macke.github.io/VoxelSpace/images/thumbnails/C18W.png"&gt;
&lt;img src="https://s-macke.github.io/VoxelSpace/images/thumbnails/D18.png"&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://s-macke.github.io/VoxelSpace/maps/C19W.png"&gt;color&lt;/a&gt;,
&lt;a href="https://s-macke.github.io/VoxelSpace/maps/D19.png"&gt;height&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://s-macke.github.io/VoxelSpace/images/thumbnails/C19W.png"&gt;
&lt;img src="https://s-macke.github.io/VoxelSpace/images/thumbnails/D19.png"&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://s-macke.github.io/VoxelSpace/maps/C20W.png"&gt;color&lt;/a&gt;,
&lt;a href="https://s-macke.github.io/VoxelSpace/maps/D20.png"&gt;height&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://s-macke.github.io/VoxelSpace/images/thumbnails/C20W.png"&gt;
&lt;img src="https://s-macke.github.io/VoxelSpace/images/thumbnails/D20.png"&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://s-macke.github.io/VoxelSpace/maps/C21.png"&gt;color&lt;/a&gt;,
&lt;a href="https://s-macke.github.io/VoxelSpace/maps/D21.png"&gt;height&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://s-macke.github.io/VoxelSpace/images/thumbnails/C21.png"&gt;
&lt;img src="https://s-macke.github.io/VoxelSpace/images/thumbnails/D21.png"&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://s-macke.github.io/VoxelSpace/maps/C22W.png"&gt;color&lt;/a&gt;,
&lt;a href="https://s-macke.github.io/VoxelSpace/maps/D22.png"&gt;height&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://s-macke.github.io/VoxelSpace/images/thumbnails/C22W.png"&gt;
&lt;img src="https://s-macke.github.io/VoxelSpace/images/thumbnails/D22.png"&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://s-macke.github.io/VoxelSpace/maps/C23W.png"&gt;color&lt;/a&gt;,
&lt;a href="https://s-macke.github.io/VoxelSpace/maps/D21.png"&gt;height&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://s-macke.github.io/VoxelSpace/images/thumbnails/C23W.png"&gt;
&lt;img src="https://s-macke.github.io/VoxelSpace/images/thumbnails/D21.png"&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://s-macke.github.io/VoxelSpace/maps/C24W.png"&gt;color&lt;/a&gt;,
&lt;a href="https://s-macke.github.io/VoxelSpace/maps/D24.png"&gt;height&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://s-macke.github.io/VoxelSpace/images/thumbnails/C24W.png"&gt;
&lt;img src="https://s-macke.github.io/VoxelSpace/images/thumbnails/D24.png"&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://s-macke.github.io/VoxelSpace/maps/C25W.png"&gt;color&lt;/a&gt;,
&lt;a href="https://s-macke.github.io/VoxelSpace/maps/D25.png"&gt;height&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://s-macke.github.io/VoxelSpace/images/thumbnails/C25W.png"&gt;
&lt;img src="https://s-macke.github.io/VoxelSpace/images/thumbnails/D25.png"&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://s-macke.github.io/VoxelSpace/maps/C26W.png"&gt;color&lt;/a&gt;,
&lt;a href="https://s-macke.github.io/VoxelSpace/maps/D18.png"&gt;height&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://s-macke.github.io/VoxelSpace/images/thumbnails/C26W.png"&gt;
&lt;img src="https://s-macke.github.io/VoxelSpace/images/thumbnails/D18.png"&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://s-macke.github.io/VoxelSpace/maps/C27W.png"&gt;color&lt;/a&gt;,
&lt;a href="https://s-macke.github.io/VoxelSpace/maps/D15.png"&gt;height&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://s-macke.github.io/VoxelSpace/images/thumbnails/C27W.png"&gt;
&lt;img src="https://s-macke.github.io/VoxelSpace/images/thumbnails/D15.png"&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://s-macke.github.io/VoxelSpace/maps/C28W.png"&gt;color&lt;/a&gt;,
&lt;a href="https://s-macke.github.io/VoxelSpace/maps/D25.png"&gt;height&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://s-macke.github.io/VoxelSpace/images/thumbnails/C28W.png"&gt;
&lt;img src="https://s-macke.github.io/VoxelSpace/images/thumbnails/D25.png"&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://s-macke.github.io/VoxelSpace/maps/C29W.png"&gt;color&lt;/a&gt;,
&lt;a href="https://s-macke.github.io/VoxelSpace/maps/D16.png"&gt;height&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://s-macke.github.io/VoxelSpace/images/thumbnails/C29W.png"&gt;
&lt;img src="https://s-macke.github.io/VoxelSpace/images/thumbnails/D16.png"&gt;&lt;/p&gt;
&lt;h2&gt;License&lt;/h2&gt;
&lt;p&gt;The software part of the repository is under the MIT license. Please read the license file for more information. Please keep in mind, that the Voxel Space technology might be still &lt;a href="https://patents.justia.com/assignee/novalogic-inc"&gt;patented&lt;/a&gt; in some countries. The color and height maps are reverse engineered from the game Comanche and are therefore excluded from the license.&lt;/p&gt;
&lt;div&gt;
        This site is open source. &lt;a href="https://github.com/s-macke/VoxelSpace/edit/gh-pages/README.md"&gt;Improve this page&lt;/a&gt;.
      &lt;/div&gt;
&lt;/div&gt;
</ns0:encoded></item><item><title>Hormuz crisis side effect: a sharp rise in container shipping rates</title><link>https://www.lloydslist.com/LL1157327/Hormuz-crisis-side-effect-a-sharp-rise-in-container-shipping-rates</link><pubDate>Sat, 30 May 2026 18:19:23 +0000</pubDate><comments>https://news.ycombinator.com/item?id=48339180</comments><description>&lt;a href="https://news.ycombinator.com/item?id=48339180"&gt;Comments&lt;/a&gt;</description><ns0:encoded xmlns:ns0="http://purl.org/rss/1.0/modules/content/">&lt;div class="article-body-content" morss_own_score="5.762295081967213" morss_score="19.214386336720064"&gt;
&lt;h1&gt;Hormuz crisis side effect: a sharp rise in container shipping rates&lt;/h1&gt;
&lt;h3&gt;&lt;ul&gt;
&lt;li&gt;SCFI global composite index has doubled since the war with Iran began and is at its highest point since September 2024, during the Red Sea crisis&lt;/li&gt;
&lt;li&gt;Bunker fuel costs have jumped by almost 70% and container lines are successfully passing incremental costs along to shippers&lt;/li&gt;
&lt;li&gt;Shanghai-Los Angeles spot rates are up 59% vs late February, with Shanghai-New York rates up 66%, according to Drewry assessments&lt;/li&gt;
&lt;/ul&gt;&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;time&gt;29 May 2026&lt;/time&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h6&gt;Analysis&lt;/h6&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Spot container freight rates continue their ascent as ocean carriers pass along much higher fuel costs resulting from the effective closure of the Strait of Hormuz. If the strait doesn’t reopen soon, the impact on container market could intensify&lt;/p&gt;

&lt;aside&gt;
&lt;span&gt; FREE TO READ&lt;/span&gt;
&lt;img src="https://www.lloydslist.com/-/media/lloyds-list/images/containers/2026-new-pictures/msc-zoe-in-piraeus-by-adobe.png?rev=0784eabe25ea4a59bcff9adf942f9386&amp;amp;w=790&amp;amp;hash=DD3DD28E0D7803149198A0C166D55DDC"&gt;
&lt;span&gt;&#13;
                        Source: aerial-drone - stock.adobe.com&#13;
                    &lt;/span&gt; &lt;span&gt;Asia-Med rates are still rising. Pictured: MSC Zoe in Piraeus.&lt;/span&gt;
&lt;/aside&gt;

&lt;div class="root" morss_own_score="2.9041825095057034" morss_score="141.35755262879687"&gt;
&lt;p&gt;IMPORTERS of containerised goods around the globe are paying more for their ocean transport as a result of the Hormuz crisis. &lt;/p&gt;
&lt;p&gt;In yet another side effect of the Middle East war, container lines are successfully passing along fuel costs inflated by the effective closure of the Strait of Hormuz. &lt;/p&gt;
&lt;p&gt;The Shanghai Containerized Freight Index global composite rose to 2,572 points in the week ending Friday, up 16% from the week before. It is now double its level in late February, just before the US and Israel attacked Iran. &lt;/p&gt;
&lt;p&gt;This week’s SCFI global composite reading was the highest since the week of September 6, 2024, during the Red Sea crisis.&lt;/p&gt;


 


&lt;p&gt;&lt;strong&gt;Impact of higher bunker fuel costs&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;“Geopolitical tensions in the Middle East are weighing on sentiment, with elevated bunker costs and fuel surcharges adding upward pressure across trade lanes,” said Drewry.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.seasearcher.com/company/10498/overview"&gt;Maersk&lt;/a&gt; chief executive Vincent Clerc said in a conference call that his company is paying around $500m per month in extra fuel costs due to the Hormuz crisis “that we must find a way to pass through”.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.seasearcher.com/company/6720/overview"&gt;Hapag-Lloyd&lt;/a&gt; chief executive Rolf Habben Jansen said that his company is paying €50m-€60m extra per week ($250m-$300m per month) and “rate increases have been roughly in line with the cost increase we have faced”.&lt;/p&gt;
&lt;p&gt;When importers pay more for ocean freight, it is the same as “when you go to the petrol station and you have to pay a higher price”, said Habben Jansen.&lt;/p&gt;
&lt;p&gt;Pass-along fuel costs may also be affecting peak season timing, further boosting spot rates.&lt;/p&gt;
&lt;p&gt;“Demand is being pulled forward into June ahead of the expected July 1 bunker fuel adjustments, supporting stronger shipment flows,” said Drewry, citing “early peak season” trends in both the transpacific and Asia-Europe trades.&lt;/p&gt;
&lt;p&gt;The average price of very low sulphur fuel at the top 20 bunkering hubs was $856 per tonne on Thursday, up 68% from mid-February, according to data from Ship &amp;amp; Bunker. &lt;/p&gt;
&lt;p&gt;The average price of high sulphur fuel oil was $736.50 per tonne on Thursday, up 66% versus mid-February.&lt;/p&gt;


 


&lt;p&gt;VLSFO pricing moves in line with Brent crude. The Brent price would decline if there is a peace agreement between the US and Iran, or surge if the Strait of Hormuz remains effectively closed for longer.&lt;/p&gt;
&lt;p&gt;Neil Chapman, senior vice president of &lt;a href="https://www.seasearcher.com/company/5155/overview"&gt;ExxonMobil&lt;/a&gt;, issued &lt;a href="https://www.lloydslist.com/LL1157316/Crude-price-spike-from-Hormuz-crisis-is-approaching-warns-ExxonMobil-exec"&gt;a blunt public warning on Thursday&lt;/a&gt;, asserting that the dated Brent price could spike to $150-$160 per barrel if the strait doesn’t reopen in the next few weeks.&lt;/p&gt;
&lt;p&gt;If Brent goes higher, bunker costs — and shipper fuel surcharges — would also rise.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Disruption helps offset capacity overhang&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The good news for carriers is that, so far, they have been able to offset fuel costs despite an ongoing flood of newbuilding capacity. &lt;/p&gt;
&lt;p&gt;Their ability to do so relates, in part, to the Hormuz crisis. &lt;/p&gt;
&lt;p&gt;Liners’ continued aversion to the Red Sea route amid the war in the Middle East reduces effective capacity by 12%, said Constatin Baack, chief executive of boxship lessor &lt;a href="https://www.seasearcher.com/company/494712/overview"&gt;MPC Container Ships&lt;/a&gt;, on a quarterly call on Wednesday.&lt;/p&gt;
&lt;p&gt;Slow steaming due to higher bunker costs has absorbed another 2% of capacity. “With energy prices up sharply, carriers have throttled back fleet speeds,” Baack said.&lt;/p&gt;
&lt;p&gt;Port congestion takes out another 5% of capacity, bringing the total reduction of effective capacity to 19%.&lt;/p&gt;
&lt;p&gt;“On paper, supply and demand have been diverging since 2023. The market should be trending toward oversupply,” said Baack. “In reality, rates have been increasing.” &lt;/p&gt;
&lt;p&gt;According to Peter Sand, chief analyst at Xeneta, “Carriers entered the year facing a potential market collapse as services [were expected to return] to the Red Sea, but have ultimately found themselves able to charge higher and higher rates to shippers across the market.”&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Asia-Europe spot rates&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Different spot index providers use different methodologies and come up with different rate assessments, but they all show the same directional trend.&lt;/p&gt;
&lt;p&gt;The SCFI &lt;a href="https://www.seasearcher.com/place/11182/overview"&gt;Shanghai&lt;/a&gt;-Mediterranean index was at $7,500 per feu this week, up 63% versus the last week of February, just before the war began. It was the index’s highest reading since January 2025.&lt;/p&gt;
&lt;p&gt;Drewry’s World Container Index assessed the Shanghai-&lt;a href="https://www.seasearcher.com/place/15521/overview"&gt;Genoa&lt;/a&gt; spot rate at $4,253 per feu, up 50% versus late February. &lt;/p&gt;
&lt;p&gt;Xeneta’s daily assessment of average short-term rates on the Asia-Med route was $4,326 per feu on Thursday, up 30% compared to pre-war levels.&lt;/p&gt;


 


&lt;p&gt;The SCFI’s Shanghai-North Europe index was at $4,949 per feu this week, up 74% versus late February to its highest point since January 2025.&lt;/p&gt;
&lt;p&gt;The WCI Shanghai-&lt;a href="https://www.seasearcher.com/place/1830/overview"&gt;Rotterdam&lt;/a&gt; index was at $2,861 per feu, up 37% since before the war, and Xeneta’s Asia-North Europe assessment was at $2,880 per feu, up 30%.&lt;/p&gt;
&lt;p&gt;“As the early peak season approaches and carriers continue to raise FAK rates, we expect rates to rise further in the coming weeks,” said Drewry.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Transpacific spot rates&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;US importers are now dealing with two policy decisions of US President Donald Trump: the attack on Iran and tariffs.&lt;/p&gt;
&lt;p&gt;US importers continue to face steep tariff bills on top of rising freight costs due to fuel, even after the Supreme Court ruled against Trump’s emergency tariffs in February.&lt;/p&gt;
&lt;p&gt;According to the Budget Lab at Yale, the current average tariff rate paid by US importers is 11.8%, the highest since the 1940s, excluding 2025. That is almost six times the 2% average at the beginning of Trump’s second term.&lt;/p&gt;
&lt;p&gt;Nevertheless, US import demand remains resilient, supporting recent spot rate gains by carriers.&lt;/p&gt;
&lt;p&gt;The SCFI Shanghai-US west coast index was at $4,149 per feu this week, up 129% versus late February. The SCFI Shanghai-US east coast index was at $5,333 per feu, up 100%.&lt;/p&gt;
&lt;p&gt;A year ago, Asia-US spot rates were even higher, as that was the period when Trump gave a temporary tariff reprieve, allowing US importers to frontload.&lt;/p&gt;


 


&lt;p&gt;The WCI assessed Shanghai-&lt;a href="https://www.seasearcher.com/place/14977/overview"&gt;Los Angeles&lt;/a&gt; rates at $3,473 per feu this week, up 59% from late February, and Shanghai-&lt;a href="https://www.seasearcher.com/place/14572/overview"&gt;New York&lt;/a&gt; rates at $4,597 per feu, up 66%.&lt;/p&gt;
&lt;p&gt;“With early peak-season trends emerging and seasonal demand strengthening through June, we expect further upward pressure on [transpacific] rates,” said Drewry.&lt;/p&gt;
&lt;p&gt;Xeneta’s assessment of average Asia-US west coast spot rates came in at $3,624 per feu on Thursday, up 74% versus late February. Xeneta’s Asia-US east coast assessment was $4,367 per feu, up 65%.&lt;/p&gt;
&lt;p&gt;“There is no hiding place from this market turmoil,” said Sand. &lt;/p&gt;
&lt;p&gt;“The June increases on the transpacific were driven mainly by the market mid-low [the midpoint between the low and the average], which are the rates generally paid by the larger-volume shippers who command greater negotiating power.”&lt;/p&gt;
&lt;/div&gt;

&lt;/div&gt;
</ns0:encoded></item></channel></rss>