+
+/*
+ * API
+ */
+
+VG_STATIC int ray_hit_is_ramp( ray_hit *hit );
+VG_STATIC struct world_material *ray_hit_material( ray_hit *hit );
+VG_STATIC void ray_world_get_tri( ray_hit *hit, v3f tri[3] );
+VG_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
+ * -----------------------------------------------------------------------------
+ */
+
+VG_STATIC int world_stop_sound( int argc, const char *argv[] )
+{
+ /*
+ * None of our world audio runs as one shots, they always have a player.
+ * Therefore it is safe to delete clip data after the players are
+ * disconnected
+ */
+ audio_lock();
+ for( int i=0; i<world.audio_things_count; i++ )
+ {
+ struct world_audio_thing *at = &world.audio_things[i];
+
+ if( audio_player_is_playing( &at->player ) )
+ {
+ u32 cflags = audio_player_get_flags( &at->player );
+ audio_player_set_flags( &at->player, cflags | AUDIO_FLAG_KILL );
+ }
+ }
+ audio_unlock();
+
+ return 0;
+}
+
+VG_STATIC int world_change_world( int argc, const char *argv[] )
+{
+ if( argc == 0 )
+ {
+ vg_info( "%s\n", world.world_name );
+ return 0;
+ }
+ else
+ {
+ vg_info( "Switching world...\n" );
+ strcpy( world.world_name, argv[0] );
+ world.switching_to_new_world = 1;
+ world_stop_sound( 0, NULL );
+ }
+
+ return 0;
+}
+
+VG_STATIC void world_init(void)