+ glmesh skybox, skydome;
+ mdl_submesh dome_upper, dome_lower;
+
+ glmesh cars;
+ mdl_submesh car_holden;
+
+ /* Load time */
+
+ struct instance_cache
+ {
+ mdl_header *mdl;
+ u32 pstr_file;
+ }
+ * instance_cache;
+ u32 instance_cache_count,
+ instance_cache_cap;
+
+ v3f render_gate_pos;
+ int active_route_board;
+}
+world ;
+
+/*
+ * API
+ */
+
+static int ray_hit_is_ramp( ray_hit *hit );
+static int ray_hit_is_terrain( ray_hit *hit );
+static void ray_world_get_tri( ray_hit *hit, v3f tri[3] );
+static int ray_world( v3f pos, v3f dir, ray_hit *hit );
+
+/*
+ * Submodules
+ */
+#include "world_routes.h"
+#include "world_sfd.h"
+#include "world_render.h"
+#include "world_water.h"
+#include "world_gen.h"
+#include "world_gate.h"
+
+/*
+ * -----------------------------------------------------------------------------
+ * Events
+ * -----------------------------------------------------------------------------
+ */
+
+static void world_init(void)
+{
+ world.sky_rate = 1.0;
+ world.sky_target_rate = 1.0;
+
+ shader_terrain_register();
+ shader_sky_register();
+ shader_planeinf_register();
+ shader_gpos_register();
+ shader_fscolour_register();
+ shader_alphatest_register();
+
+ vg_info( "Loading world resources\n" );
+
+ VG_REQUIRED_ASSET( mdl_header*, mcars, mdl_load, "models/rs_cars.mdl" );
+ VG_REQUIRED_ASSET( mdl_header*, msky, mdl_load, "models/rs_skydome.mdl" );
+
+ mdl_node *nholden = mdl_node_from_name( mcars, "holden" );
+ world.car_holden = *mdl_node_submesh( mcars, nholden, 0 );
+
+ mdl_node *nlower = mdl_node_from_name( msky, "dome_lower" ),
+ *nupper = mdl_node_from_name( msky, "dome_upper" );