rewrite block system

isolation_bkp/dynres
Dominik Madarász 2021-11-02 12:49:03 +01:00
parent f8da96b968
commit 365b3e8ee3
13 changed files with 127 additions and 127 deletions

View File

@ -16,6 +16,15 @@ typedef enum {
// NOTE(zaklaus): blocks // NOTE(zaklaus): blocks
ASSET_FENCE, ASSET_FENCE,
ASSET_DEV,
ASSET_GROUND,
ASSET_DIRT,
ASSET_WATER,
ASSET_LAVA,
ASSET_WALL,
ASSET_HILL,
ASSET_HILL_SNOW,
ASSET_HOLE,
MAX_ASSETS, MAX_ASSETS,
FORCE_ASSET_UINT16 = UINT16_MAX FORCE_ASSET_UINT16 = UINT16_MAX

View File

@ -1,16 +1,24 @@
#include "assets.h" #include "assets.h"
#define ASSET_TEX(asset)\
{\
.id = asset,\
.kind = AKIND_TEXTURE,\
}
static asset assets[] = { static asset assets[] = {
{ ASSET_TEX(ASSET_EMPTY),
.id = ASSET_EMPTY, ASSET_TEX(ASSET_DEMO_ICEMAKER),
.kind = AKIND_TEXTURE,
}, // NOTE(zaklaus): blocks
{ ASSET_TEX(ASSET_FENCE),
.id = ASSET_DEMO_ICEMAKER, ASSET_TEX(ASSET_DEV),
.kind = AKIND_TEXTURE, ASSET_TEX(ASSET_GROUND),
}, ASSET_TEX(ASSET_DIRT),
{ ASSET_TEX(ASSET_WATER),
.id = ASSET_FENCE, ASSET_TEX(ASSET_LAVA),
.kind = AKIND_TEXTURE, ASSET_TEX(ASSET_WALL),
} ASSET_TEX(ASSET_HILL),
ASSET_TEX(ASSET_HILL_SNOW),
ASSET_TEX(ASSET_HOLE),
}; };

View File

@ -58,7 +58,7 @@ ActSpawnCirclingDriver(void) {
void void
ActPlaceIceRink(void) { ActPlaceIceRink(void) {
ecs_entity_t plr = camera_get().ent_id; ecs_entity_t plr = camera_get().ent_id;
uint8_t watr_id = blocks_find(BLOCK_BIOME_DEV, BLOCK_KIND_WATER); uint8_t watr_id = blocks_find(ASSET_WATER);
Position const *p = ecs_get(world_ecs(), plr, Position); Position const *p = ecs_get(world_ecs(), plr, Position);
float const bs = WORLD_BLOCK_SIZE; float const bs = WORLD_BLOCK_SIZE;

View File

@ -96,7 +96,7 @@ void entity_view_mark_for_fadein(entity_view_tbl *map, uint64_t ent_id) {
void entity_view_update_chunk_texture(entity_view_tbl *map, uint64_t ent_id, void *world_view) { void entity_view_update_chunk_texture(entity_view_tbl *map, uint64_t ent_id, void *world_view) {
entity_view *view = entity_view_tbl_get(map, ent_id); entity_view *view = entity_view_tbl_get(map, ent_id);
if (view->kind != EKIND_CHUNK) return; if (view->kind != EKIND_CHUNK) return;
blocks_build_chunk_tex(ent_id, view->blocks, view->outer_blocks, world_view); blocks_build_chunk_tex(ent_id, view->blocks, world_view);
} }
void entity_view_remove_chunk_texture(entity_view_tbl *map, uint64_t ent_id) { void entity_view_remove_chunk_texture(entity_view_tbl *map, uint64_t ent_id) {

View File

@ -12,31 +12,19 @@ Texture2D LoadImageEco(const char *name) {
return LoadTexture(filename); return LoadTexture(filename);
} }
Texture2D texgen_build_block(uint32_t biome, uint32_t kind) {
switch (biome) {
case BLOCK_BIOME_DEV: {
switch (kind) {
case BLOCK_KIND_GROUND: return LoadImageEco("grass");
case BLOCK_KIND_DIRT: return LoadImageEco("dirt");
case BLOCK_KIND_WALL: return LoadImageEco("asphalt");
case BLOCK_KIND_HILL_SNOW:
case BLOCK_KIND_HILL: return LoadImageEco("rock");
case BLOCK_KIND_WATER: return LoadImageEco("water");
case BLOCK_KIND_LAVA: return LoadImageEco("lava");
}
}
}
Image img = GenImageColor(WORLD_BLOCK_SIZE,WORLD_BLOCK_SIZE,ColorFromHSV(biome+kind*30, 0.13f, 0.89f));
Texture2D tex = LoadTextureFromImage(img);
UnloadImage(img);
return tex;
}
Texture2D texgen_build_sprite(asset_id id) { Texture2D texgen_build_sprite(asset_id id) {
switch (id) { switch (id) {
case ASSET_DEMO_ICEMAKER: return LoadImageEco("demo_icemaker"); case ASSET_DEMO_ICEMAKER: return LoadImageEco("demo_icemaker");
// NOTE(zaklaus): blocks
case ASSET_FENCE: return LoadImageEco("fence"); case ASSET_FENCE: return LoadImageEco("fence");
case ASSET_GROUND: return LoadImageEco("grass");
case ASSET_DIRT: return LoadImageEco("dirt");
case ASSET_WALL: return LoadImageEco("asphalt");
case ASSET_HILL_SNOW:
case ASSET_HILL: return LoadImageEco("rock");
case ASSET_WATER: return LoadImageEco("water");
case ASSET_LAVA: return LoadImageEco("lava");
default: { default: {
Image img = GenImageColor(1, 1, RAYWHITE); Image img = GenImageColor(1, 1, RAYWHITE);

View File

@ -4,5 +4,4 @@
#include "world/blocks.h" #include "world/blocks.h"
#include "assets.h" #include "assets.h"
Texture2D texgen_build_block(uint32_t biome, uint32_t kind);
Texture2D texgen_build_sprite(asset_id id); Texture2D texgen_build_sprite(asset_id id);

View File

@ -40,7 +40,7 @@ void item_use(ecs_world_t *ecs, ItemDrop *it, Position p) {
switch (item_get_usage(item_id)) { switch (item_get_usage(item_id)) {
case UKIND_PLACE:{ case UKIND_PLACE:{
world_block_lookup l = world_block_from_realpos(p.x, p.y); world_block_lookup l = world_block_from_realpos(p.x, p.y);
if (world_chunk_place_block(l.chunk_id, l.id, blocks_find(desc->place.biome, desc->place.kind)) ) if (world_chunk_place_block(l.chunk_id, l.id, blocks_find(desc->place.kind)) )
it->quantity--; it->quantity--;
}break; }break;
} }

View File

@ -19,8 +19,7 @@ typedef struct {
// NOTE(zaklaus): usage data // NOTE(zaklaus): usage data
union { union {
struct { struct {
block_biome biome; asset_id kind;
block_kind kind;
} place; } place;
}; };
} item_desc; } item_desc;

View File

@ -1,18 +1,22 @@
#include "items.h" #include "items.h"
#define ITEM_BLOCK(asset, qty, build_asset)\
{\
.kind = asset,\
.usage = UKIND_PLACE,\
.max_quantity = qty,\
.place = {\
.kind = build_asset,\
}\
}
#define ITEM_SELF(asset, qty) ITEM_BLOCK(asset, qty, asset)
static item_desc items[] = { static item_desc items[] = {
{ {
.kind = 0, .kind = 0,
.max_quantity = 0, .max_quantity = 0,
}, },
{ ITEM_BLOCK(ASSET_DEMO_ICEMAKER, 64, ASSET_WATER),
.kind = ASSET_DEMO_ICEMAKER, ITEM_SELF(ASSET_FENCE, 64),
.usage = UKIND_PLACE, };
.max_quantity = 64,
.place = {
.biome = BLOCK_BIOME_DEV,
.kind = BLOCK_KIND_WATER,
}
}
};

View File

@ -20,50 +20,38 @@ static void chunks_unload_textures(uint64_t key, RenderTexture2D *value) {
} }
typedef struct { typedef struct {
char *name; asset_id kind;
uint32_t flags; uint32_t flags;
uint32_t kind;
uint32_t biome;
char symbol; char symbol;
float drag; float drag;
float friction; float friction;
float bounce; float bounce;
// NOTE(zaklaus): viewer data // NOTE(zaklaus): viewer data
Texture2D img; uint16_t slot;
} block; } block;
#include "blocks_list.c" #include "blocks_list.c"
int32_t blocks_setup(void) { int32_t blocks_setup(void) {
for (uint32_t i=0; i<BLOCKS_COUNT; i++) { for (uint32_t i=0; i<BLOCKS_COUNT; i++) {
block *b = &blocks[i]; blocks[i].slot = assets_find(blocks[i].kind);
b->img = texgen_build_block(b->biome, b->kind);
} }
blocks__chunk_tbl_init(&baked_chunks, zpl_heap()); blocks__chunk_tbl_init(&baked_chunks, zpl_heap());
return 0; return 0;
} }
void blocks_destroy(void) { void blocks_destroy(void) {
for (uint32_t i=0; i<BLOCKS_COUNT; i++) {
UnloadTexture(blocks[i].img);
}
blocks__chunk_tbl_map_mut(&baked_chunks, chunks_unload_textures); blocks__chunk_tbl_map_mut(&baked_chunks, chunks_unload_textures);
blocks__chunk_tbl_destroy(&baked_chunks); blocks__chunk_tbl_destroy(&baked_chunks);
} }
uint8_t blocks_find(uint32_t biome, uint32_t kind) { uint8_t blocks_find(asset_id kind) {
for (uint32_t i=0; i<BLOCKS_COUNT; i++) { for (uint8_t i=0; i<BLOCKS_COUNT; i++) {
if (blocks[i].biome == biome && blocks[i].kind == kind) if (blocks[i].kind == kind)
return i; return i;
} }
return BLOCK_INVALID; return 0xF;
}
char *blocks_get_name(uint8_t id) {
return blocks[id].name;
} }
char blocks_get_symbol(uint8_t id) { char blocks_get_symbol(uint8_t id) {
@ -74,14 +62,6 @@ uint32_t blocks_get_flags(uint8_t id) {
return blocks[id].flags; return blocks[id].flags;
} }
uint32_t blocks_get_biome(uint8_t id) {
return blocks[id].biome;
}
uint32_t blocks_get_kind(uint8_t id) {
return blocks[id].kind;
}
float blocks_get_drag(uint8_t id) { float blocks_get_drag(uint8_t id) {
return blocks[id].drag; return blocks[id].drag;
} }
@ -95,39 +75,25 @@ float blocks_get_bounce(uint8_t id) {
} }
void *blocks_get_img(uint8_t id) { void *blocks_get_img(uint8_t id) {
return (void*)&blocks[id].img; return assets_get_tex(blocks[id].slot);
} }
void blocks_build_chunk_tex(uint64_t id, uint8_t *chunk_blocks, uint8_t *outer_chunk_blocks, void *raw_view) { void blocks_build_chunk_tex(uint64_t id, uint8_t *chunk_blocks, void *raw_view) {
world_view *view = (world_view*)raw_view; world_view *view = (world_view*)raw_view;
uint16_t blk_dims = WORLD_BLOCK_SIZE * WORLD_TEXTURE_BLOCK_SCALE; uint16_t blk_dims = (uint16_t)(WORLD_BLOCK_SIZE * WORLD_TEXTURE_BLOCK_SCALE);
uint16_t dims = blk_dims * view->chunk_size; uint16_t dims = blk_dims * view->chunk_size;
RenderTexture2D canvas = LoadRenderTexture(dims, dims); RenderTexture2D canvas = LoadRenderTexture(dims, dims);
BeginTextureMode(canvas); BeginTextureMode(canvas);
ClearBackground(WHITE); ClearBackground(WHITE);
for (int y = 0; y < view->chunk_size; y += 1) { for (int y = 0; y < view->chunk_size; y += 1) {
for (int x = 0; x < view->chunk_size; x += 1) { for (int x = 0; x < view->chunk_size; x += 1) {
#if 0
Texture2D blk = blocks[chunk_blocks[(y*view->chunk_size)+x]].img;
Rectangle src = {0, 0, WORLD_BLOCK_SIZE, WORLD_BLOCK_SIZE};
Rectangle dst = {x*blk_dims, y*blk_dims, blk_dims, blk_dims};
DrawTexturePro(blk, src, dst, (Vector2){0.0f,0.0f}, 0.0f, WHITE);
#else
static float rots[] = { 0.0f, 90.0f, 180.f, 270.0f }; static float rots[] = { 0.0f, 90.0f, 180.f, 270.0f };
float rot = rots[(int32_t)(perlin_fbm(view->seed, x, y, 1.2f, 3) * 4.0f) % 4]; float rot = rots[(int32_t)(perlin_fbm(view->seed, x, y, 1.2f, 3) * 4.0f) % 4];
float half_block = blk_dims / 2.0f; float half_block = blk_dims / 2.0f;
Texture2D blk = blocks[chunk_blocks[(y*view->chunk_size)+x]].img; Texture2D blk = *(Texture2D*)blocks_get_img(chunk_blocks[(y*view->chunk_size)+x]);
Rectangle src = {0, 0, WORLD_BLOCK_SIZE, WORLD_BLOCK_SIZE}; Rectangle src = {0, 0, WORLD_BLOCK_SIZE, WORLD_BLOCK_SIZE};
Rectangle dst = {x*blk_dims + half_block, y*blk_dims + half_block, blk_dims, blk_dims}; Rectangle dst = {x*blk_dims + half_block, y*blk_dims + half_block, blk_dims, blk_dims};
DrawTexturePro(blk, src, dst, (Vector2){half_block, half_block}, rot, WHITE); DrawTexturePro(blk, src, dst, (Vector2){half_block, half_block}, rot, WHITE);
#if 0
if (outer_chunk_blocks[(y*view->chunk_size)+x] != 0) {
Texture2D blk2 = blocks[outer_chunk_blocks[(y*view->chunk_size)+x]].img;
DrawTexturePro(blk2, src, dst, (Vector2){half_block, half_block}, rot, WHITE);
}
#endif
#endif
} }
} }
EndTextureMode(); EndTextureMode();

View File

@ -1,25 +1,20 @@
#pragma once #pragma once
#include "system.h" #include "system.h"
#include "assets.h"
#define BLOCK_INVALID 0xF
typedef enum { typedef enum {
BLOCK_FLAG_COLLISION = (1 << 1), BLOCK_FLAG_COLLISION = (1 << 1),
BLOCK_FLAG_HAZARD = (1 << 2), BLOCK_FLAG_HAZARD = (1 << 2),
} block_flags; } block_flags;
#include "blocks_info.h"
int32_t blocks_setup(void); int32_t blocks_setup(void);
void blocks_destroy(void); void blocks_destroy(void);
uint8_t blocks_find(uint32_t biome, uint32_t kind); uint8_t blocks_find(asset_id kind);
char *blocks_get_name(uint8_t id); char *blocks_get_name(uint8_t id);
char blocks_get_symbol(uint8_t id); char blocks_get_symbol(uint8_t id);
uint32_t blocks_get_flags(uint8_t id); uint32_t blocks_get_flags(uint8_t id);
uint32_t blocks_get_biome(uint8_t id);
uint32_t blocks_get_kind(uint8_t id);
float blocks_get_drag(uint8_t id); float blocks_get_drag(uint8_t id);
float blocks_get_friction(uint8_t id); float blocks_get_friction(uint8_t id);
float blocks_get_bounce(uint8_t id); float blocks_get_bounce(uint8_t id);
@ -27,6 +22,6 @@ float blocks_get_bounce(uint8_t id);
// NOTE(zaklaus): viewer-related functions // NOTE(zaklaus): viewer-related functions
void *blocks_get_img(uint8_t id); void *blocks_get_img(uint8_t id);
void blocks_build_chunk_tex(uint64_t id, uint8_t *blocks, uint8_t *outer_blocks, void *view); void blocks_build_chunk_tex(uint64_t id, uint8_t *blocks, void *view);
void *blocks_get_chunk_tex(uint64_t id); void *blocks_get_chunk_tex(uint64_t id);
void blocks_remove_chunk_tex(uint64_t id); void blocks_remove_chunk_tex(uint64_t id);

View File

@ -1,12 +1,18 @@
#include "world/blocks.h" #include "world/blocks.h"
#define BLOCK(a, f, s, ...)\
{\
.kind = a, .flags = f, .symbol = s, __VA_ARGS__\
}
static block blocks[] = { static block blocks[] = {
{.name = "empty", .flags = 0, .kind = BLOCK_KIND_EMPTY, .biome = 0, .symbol = ' ', .drag = 1.0f, .friction = 1.0f }, BLOCK(ASSET_EMPTY, 0, ' ', .drag = 1.0f, .friction = 1.0f),
{.name = "base-ground", .flags = 0, .kind = BLOCK_KIND_GROUND, .biome = 0, .symbol = '.', .drag = 1.0f, .friction = 1.0f }, BLOCK(ASSET_GROUND, 0, '.', .drag = 1.0f, .friction = 1.0f),
{.name = "base-dirt", .flags = 0, .kind = BLOCK_KIND_DIRT, .biome = 0, .symbol = ',', .drag = 2.1f , .friction = 1.0f }, BLOCK(ASSET_DIRT, 0, ',', .drag = 2.1f , .friction = 1.0f),
{.name = "base-wall", .flags = BLOCK_FLAG_COLLISION, .kind = BLOCK_KIND_WALL, .biome = 0, .symbol = '#', .drag = 1.0f , .friction = 1.0f, .bounce = 1.0f }, BLOCK(ASSET_WALL, BLOCK_FLAG_COLLISION, '#', .drag = 1.0f , .friction = 1.0f, .bounce = 1.0f),
{.name = "base-hill", .flags = BLOCK_FLAG_COLLISION, .kind = BLOCK_KIND_HILL, .biome = 0, .symbol = '^', .drag = 1.0f , .friction = 1.0f }, BLOCK(ASSET_HILL, BLOCK_FLAG_COLLISION, '^', .drag = 1.0f , .friction = 1.0f),
{.name = "base-hill-snow", .flags = BLOCK_FLAG_COLLISION, .kind = BLOCK_KIND_HILL_SNOW, .biome = 0, .symbol = '*', .drag = 1.0f , .friction = 1.0f }, BLOCK(ASSET_HILL_SNOW, BLOCK_FLAG_COLLISION, '*', .drag = 1.0f , .friction = 1.0f),
{.name = "base-water", .flags = 0, .kind = BLOCK_KIND_WATER, .biome = 0, .symbol = '~', .drag = 0.11f , .friction = 1.0f }, BLOCK(ASSET_WATER, 0, '~', .drag = 0.11f , .friction = 1.0f),
{.name = "base-lava", .flags = BLOCK_FLAG_HAZARD, .kind = BLOCK_KIND_LAVA, .biome = 0, .symbol = '!', .drag = 6.2f , .friction = 4.0f }, BLOCK(ASSET_LAVA, BLOCK_FLAG_HAZARD, '!', .drag = 6.2f , .friction = 4.0f),
BLOCK(ASSET_FENCE, BLOCK_FLAG_COLLISION, '#', .drag = 1.0f , .friction = 1.0f, .bounce = 1.0f),
}; };

View File

@ -10,6 +10,7 @@
#include "modules/components.h" #include "modules/components.h"
#include "vehicle.h" #include "vehicle.h"
#include "items.h" #include "items.h"
#include "world/blocks_info.h"
#define WORLD_BLOCK_OBSERVER(name) uint8_t name(uint8_t id, uint32_t block_idx) #define WORLD_BLOCK_OBSERVER(name) uint8_t name(uint8_t id, uint32_t block_idx)
typedef WORLD_BLOCK_OBSERVER(world_block_observer_proc); typedef WORLD_BLOCK_OBSERVER(world_block_observer_proc);
@ -17,6 +18,27 @@ typedef WORLD_BLOCK_OBSERVER(world_block_observer_proc);
#define WORLD_PERLIN_FREQ 100 #define WORLD_PERLIN_FREQ 100
#define WORLD_PERLIN_OCTAVES 1 #define WORLD_PERLIN_OCTAVES 1
#define BLOCK_INVALID 0xF
uint8_t worldgen_biome_find(uint32_t biome, uint32_t kind) {
asset_id asset = ASSET_INVALID;
switch (biome) {
case BLOCK_BIOME_DEV: {
switch (kind) {
case BLOCK_KIND_GROUND: asset = ASSET_GROUND; break;
case BLOCK_KIND_DIRT: asset = ASSET_DIRT; break;
case BLOCK_KIND_WALL: asset = ASSET_WALL; break;
case BLOCK_KIND_HILL_SNOW:
case BLOCK_KIND_HILL: asset = ASSET_HILL; break;
case BLOCK_KIND_WATER: asset = ASSET_WATER; break;
case BLOCK_KIND_LAVA: asset = ASSET_LAVA; break;
}
}
}
return blocks_find(asset);
}
static world_data *world; static world_data *world;
static void world_fill_rect(uint8_t id, uint32_t x, uint32_t y, uint32_t w, uint32_t h, world_block_observer_proc *proc) { static void world_fill_rect(uint8_t id, uint32_t x, uint32_t y, uint32_t w, uint32_t h, world_block_observer_proc *proc) {
@ -66,18 +88,14 @@ static void world_fill_rect_anchor(uint8_t id, uint32_t x, uint32_t y, uint32_t
} }
static WORLD_BLOCK_OBSERVER(shaper) { static WORLD_BLOCK_OBSERVER(shaper) {
uint32_t biome = blocks_get_biome(id); uint32_t kind = id;
uint32_t kind = blocks_get_kind(id); uint32_t old_kind = world->data[block_idx];
uint32_t old_biome = blocks_get_biome(world->data[block_idx]);
uint32_t old_kind = blocks_get_kind(world->data[block_idx]);
if (biome == old_biome) { if (kind == BLOCK_KIND_WALL && kind == old_kind) {
if (kind == BLOCK_KIND_WALL && kind == old_kind) { return worldgen_biome_find(BLOCK_BIOME_DEV, BLOCK_KIND_HILL);
return blocks_find(biome, BLOCK_KIND_HILL); }
} if (kind == BLOCK_KIND_HILL && kind == old_kind) {
if (kind == BLOCK_KIND_HILL && kind == old_kind) { return worldgen_biome_find(BLOCK_BIOME_DEV, BLOCK_KIND_HILL_SNOW);
return blocks_find(biome, BLOCK_KIND_HILL_SNOW);
}
} }
return id; return id;
@ -134,11 +152,11 @@ int32_t worldgen_test(world_data *wld) {
// TODO: perform world gen // TODO: perform world gen
// atm, we will fill the world with ground and surround it by walls // atm, we will fill the world with ground and surround it by walls
uint8_t wall_id = blocks_find(BLOCK_BIOME_DEV, BLOCK_KIND_WALL); uint8_t wall_id = worldgen_biome_find(BLOCK_BIOME_DEV, BLOCK_KIND_WALL);
uint8_t grnd_id = blocks_find(BLOCK_BIOME_DEV, BLOCK_KIND_GROUND); uint8_t grnd_id = worldgen_biome_find(BLOCK_BIOME_DEV, BLOCK_KIND_GROUND);
uint8_t dirt_id = blocks_find(BLOCK_BIOME_DEV, BLOCK_KIND_DIRT); uint8_t dirt_id = worldgen_biome_find(BLOCK_BIOME_DEV, BLOCK_KIND_DIRT);
uint8_t watr_id = blocks_find(BLOCK_BIOME_DEV, BLOCK_KIND_WATER); uint8_t watr_id = worldgen_biome_find(BLOCK_BIOME_DEV, BLOCK_KIND_WATER);
uint8_t lava_id = blocks_find(BLOCK_BIOME_DEV, BLOCK_KIND_LAVA); uint8_t lava_id = worldgen_biome_find(BLOCK_BIOME_DEV, BLOCK_KIND_LAVA);
srand(world->seed); srand(world->seed);
@ -197,6 +215,14 @@ int32_t worldgen_test(world_data *wld) {
dest->x = RAND_RANGE(0, world->dim*WORLD_BLOCK_SIZE); dest->x = RAND_RANGE(0, world->dim*WORLD_BLOCK_SIZE);
dest->y = RAND_RANGE(0, world->dim*WORLD_BLOCK_SIZE); dest->y = RAND_RANGE(0, world->dim*WORLD_BLOCK_SIZE);
} }
for (int i=0; i<RAND_RANGE(328, 164); i++) {
uint64_t e = item_spawn(ASSET_FENCE, 64);
Position *dest = ecs_get_mut(world_ecs(), e, Position, NULL);
dest->x = RAND_RANGE(0, world->dim*WORLD_BLOCK_SIZE);
dest->y = RAND_RANGE(0, world->dim*WORLD_BLOCK_SIZE);
}
#endif #endif
return WORLD_ERROR_NONE; return WORLD_ERROR_NONE;